Display current date when saving/editing span (angularjs) - javascript

I have a fairly simple task list using angularjs and I would like to save the time when each task was created and update that time if the task is edited.
I'm thinking I could use something like this to display the current time, but I'm not sure how to do it on save/edit.
HTML:
<div ng-controller="TodoListController">
<form ng-submit="addTodo()" name="form">
<input type="text" ng-model="todoText" size="30" placeholder="Add New Entry" required id="textField" ng-model="myVar">
<input class="btn-primary" type="submit" value="Save">
</form>
<ul class="unstyled">
<li ng-repeat="todo in todos | orderBy : $index:true">
<button type="button" class="close" aria-label="Close" ng-click="remove(todo)">
<span aria-hidden="true">×</span>
</button>
<span class="done-{{todo.done}}" ng-style="todo.customStyle" ng-hide="todo.editing" ng-click="updateVar($event)">{{todo.text}}</span>
<input type="text" ng-show="todo.editing" ng-model="todo.text">
<button type="submit" ng-hide="todo.editing" ng-click="change(todo); todo.editing === true">Edit</button>
<button type="submit" ng-show="todo.editing" ng-click="save($index); todo.editing === false">Save</button>
<button type="submit" ng-show="todo.editing" ng-click="cancel($index); todo.editing === false">Cancel</button>
</li>
</ul>
</div>
JS:
var app = angular.module('todoApp', []);
app.controller('TodoListController', ['$scope', function ($scope) {
$scope.todos = [];
$scope.newField = [];
$scope.customStyle = {};
$scope.addTodo = function () {
$scope.todos.push({text: $scope.todoText, done: false, editing: false});
$scope.todoText = '';
};
$scope.remaining = function () {
var count = 0;
angular.forEach($scope.todos, function (todo) {
count += todo.done ? 0 : 1;
});
return count;
};
$scope.delete = function () {
var oldTodos = $scope.todos;
$scope.todos = [];
angular.forEach(oldTodos, function (todo) {
if (!todo.done) $scope.todos.push(todo);
});
};
$scope.remove = function () {
$scope.todos.splice(this.$index, 1);
};
$scope.change = function (field) {
var todoIndex = $scope.todos.indexOf(field);
$scope.newField[todoIndex] = angular.copy(field);
$scope.todos[todoIndex].editing = true;
};
$scope.save = function (index) {
$scope.todos[index].editing = false;
};
$scope.cancel = function (index) {
$scope.todos[index] = $scope.newField[index];
};
$scope.updateVar = function (event) {
$scope.myVar = angular.element(event.target).text();
};
$scope.editKeyword = function (name, index) {
$scope.mode[index] = 'edit';
console.log(name);
};
}]);

Just add a todoDate attribute in the todo model like
$scope.todos.push({text: $scope.todoText, done: false, editing: false, todoDate: new Date()});
and update it when the user updates the todo object ie save()
$scope.save = function (index) {
$scope.todos[index].editing = false;
$scope.todos[index].todoDate = new Date();
};
Hope it helps.

When you call save function to add new todos simply add the createdOn field.
$scope.save = function (index) {
$scope.todos[index].editing = false;
$scope.todos[index].createdOn = new Date().getTime();
};
Now when user edits the todo and change function is called, do as below
$scope.change = function (field) {
var todoIndex = $scope.todos.indexOf(field);
$scope.newField[todoIndex] = angular.copy(field);
$scope.todos[todoIndex].editing = true;
$scope.todos[todoIndex].LastModifyOn = new Date().getTime();
};
Now if this updated todo is again edited by the user we need to simply call change function and it will update the LastModifyOn filed.
So by doing this, we can keep both data like when was the todo created and when was it last gets updated.

var app = angular.module('todoApp', []);
app.controller('TodoListController', ['$scope', function ($scope) {
$scope.todos = [];
$scope.newField = [];
$scope.customStyle = {};
$scope.addTodo = function () {
$scope.todos.push({text: $scope.todoText, done: false, editing: false, created: new Date()});
$scope.todoText = '';
};
$scope.remaining = function () {
var count = 0;
angular.forEach($scope.todos, function (todo) {
count += todo.done ? 0 : 1;
});
return count;
};
$scope.delete = function () {
var oldTodos = $scope.todos;
$scope.todos = [];
angular.forEach(oldTodos, function (todo) {
if (!todo.done) $scope.todos.push(todo);
});
};
$scope.remove = function () {
$scope.todos.splice(this.$index, 1);
};
$scope.change = function (field) {
var todoIndex = $scope.todos.indexOf(field);
$scope.newField[todoIndex] = angular.copy(field);
$scope.todos[todoIndex].editing = true;
$scope.todos[todoIndex].created = new Date();
};
$scope.save = function (index) {
$scope.todos[index].editing = false;
$scope.todos[index].created = new Date();
};
$scope.cancel = function (index) {
$scope.todos[index] = $scope.newField[index];
};
$scope.updateVar = function (event) {
$scope.myVar = angular.element(event.target).text();
};
$scope.editKeyword = function (name, index) {
$scope.mode[index] = 'edit';
console.log(name);
};
}]);

Related

function in java err

I wrote a program with a pattern that takes names and numbers from inputs and stores them in an array.
And I wrote a function that takes these contacts from the array and creates tags for each contact and puts the name and number of the contact inside these tags.
The problem is that in the addbook function I called the showrecords function, then every time the existing contact list is added, the contacts are updated and the contacts are shown, but when I use the showrecords function, it gives an error inside the addbook function, which is not available.
Please help me solve my problem
function ElementBuilder(name) {
this.element = document.createElement(name);
this.appendSelector = function(selector) {
this.appendElement = document.querySelector(selector).appendChild(this.element);
return this
};
this.setAttribute = function(attribute, valueAttribute) {
this.element.setAttribute(attribute, valueAttribute)
return this;
};
this.addEventListener = function(event, fun) {
this.element.addEventListener(event, fun);
return this;
};
this.text = function(text) {
this.element.textContent = text;
return this;
};
this.build = function() {
return this.element;
};
}
const builder = {
create: function(name) {
return new ElementBuilder(name);
}
};
function PhoneBookRecord(name, phone) {
this.name = name;
this.phone = phone;
}
function PhoneBook() {
this.records = [];
const selectID = (idName) => document.getElementById(idName);
// function add contact
this.addbook = function() {
const self = this
function add() {
const letters = /^[A-Za-z]+$/;
const numbers = /^([0-9])+$/;
if ((selectID("name").value.match(letters)) && (selectID("phone").value.match(numbers))) {
const newContact = new PhoneBookRecord(selectID("name").value, selectID("phone").value);
self.records.push(newContact);
// The problem is that it cannot find this function until the contact list is displayed
showrecords();
}
return add;
}
}
}
function Render(container) {
this.container = container;
const phoneBook = new PhoneBook()
const add = phoneBook
.addbook();
const arry = phoneBook
.records;
// Function of elements Html
this.init = function() {
const btn = builder
.create("button")
.text("Add")
.addEventListener("click", add)
.setAttribute("id", "add")
.appendSelector("div")
.build();
const phoneBookContact = builder
.create("div")
.setAttribute("id", "addBook")
.appendSelector("div")
.build();
phoneBook.showrecords();
};
// Function: Read contacts from the array and display them
this.showrecords = function() {
const addBookId = document.getElementById('addBook');
const index = 0;
addBookId.innerHTML = '';
arry.forEach(elm => {
// Function of elements Html
const nameContent = builder
.create('li')
.text(`${elm.name}`)
.appendSelector("div>div")
.build();
const phoneContent = builder
.create('li')
.text(`${elm.phone}`)
.appendSelector("div>div")
.build();
});
}
}
const phoneBookContainer = document.getElementById("phone-book-container");
const app = new Render(phoneBookContainer);
app.init();
<form>
<label>Phone Book</label>
<input type="text" placeholder="name" id="name">
<input type="number" placeholder="phone" id="phone">
</form>
<div id="phone-book-container"></div>
These are the 2 steps i did to change the code and get to a working state.
Extract showrecords out of Render
pass the records to showrecords
I think this code needs a lot of work.
Here is a working JSFiddle: https://jsfiddle.net/jq5L7cdf/17/
Here is a snippet
function showrecords(arry) {
const addBookId = document.getElementById('addBook');
const index = 0;
addBookId.innerHTML = '';
arry.forEach(elm => {
// Function of elements Html
const nameContent = builder
.create('li')
.text(`${elm.name}`)
.appendSelector("div>div")
.build();
const phoneContent = builder
.create('li')
.text(`${elm.phone}`)
.appendSelector("div>div")
.build();
});
}
function ElementBuilder(name) {
this.element = document.createElement(name);
this.appendSelector = function(selector) {
this.appendElement = document.querySelector(selector).appendChild(this.element);
return this
};
this.setAttribute = function(attribute, valueAttribute) {
this.element.setAttribute(attribute, valueAttribute)
return this;
};
this.addEventListener = function(event, fun) {
this.element.addEventListener(event, fun);
return this;
};
this.text = function(text) {
this.element.textContent = text;
return this;
};
this.build = function() {
return this.element;
};
}
const builder = {
create: function(name) {
return new ElementBuilder(name);
}
};
function PhoneBookRecord(name, phone) {
this.name = name;
this.phone = phone;
}
function PhoneBook() {
this.records = [];
const selectID = (idName) => document.getElementById(idName);
// function add contact
this.addbook = function() {
const self = this
function add() {
const letters = /^[A-Za-z]+$/;
const numbers = /^([0-9])+$/;
if ((selectID("name").value.match(letters)) && (selectID("phone").value.match(numbers))) {
const newContact = new PhoneBookRecord(selectID("name").value, selectID("phone").value);
self.records.push(newContact);
// The problem is that it cannot find this function until the contact list is displayed
showrecords(self.records);
}
}
return add;
}
}
function Render(container) {
this.container = container;
const phoneBook = new PhoneBook()
const add = phoneBook
.addbook();
// Function of elements Html
this.init = function() {
const btn = builder
.create("button")
.text("Add")
.addEventListener("click", add)
.setAttribute("id", "add")
.appendSelector("div")
.build();
const phoneBookContact = builder
.create("div")
.setAttribute("id", "addBook")
.appendSelector("div")
.build();
showrecords(phoneBook.records);
};
// Function: Read contacts from the array and display them
this.showrecords = showrecords
}
const phoneBookContainer = document.getElementById("phone-book-container");
const app = new Render(phoneBookContainer);
app.init();
<form>
<label>Phone Book</label>
<input type="text" placeholder="name" id="name">
<input type="number" placeholder="phone" id="phone">
</form>
<div id="phone-book-container"></div>
EDIT:
use showrecords from Render
function ElementBuilder(name) {
this.element = document.createElement(name);
this.appendSelector = function(selector) {
this.appendElement = document.querySelector(selector).appendChild(this.element);
return this
};
this.setAttribute = function(attribute, valueAttribute) {
this.element.setAttribute(attribute, valueAttribute)
return this;
};
this.addEventListener = function(event, fun) {
this.element.addEventListener(event, fun);
return this;
};
this.text = function(text) {
this.element.textContent = text;
return this;
};
this.build = function() {
return this.element;
};
}
const builder = {
create: function(name) {
return new ElementBuilder(name);
}
};
function PhoneBookRecord(name, phone) {
this.name = name;
this.phone = phone;
}
function PhoneBook() {
this.records = [];
const selectID = (idName) => document.getElementById(idName);
// function add contact
this.addbook = function() {
const self = this
function add() {
const letters = /^[A-Za-z]+$/;
const numbers = /^([0-9])+$/;
if ((selectID("name").value.match(letters)) && (selectID("phone").value.match(numbers))) {
const newContact = new PhoneBookRecord(selectID("name").value, selectID("phone").value);
self.records.push(newContact);
// The problem is that it cannot find this function until the contact list is displayed
}
}
return add;
}
}
function Render(container) {
this.container = container;
const phoneBook = new PhoneBook()
const add = phoneBook
.addbook();
this.addEntry = () => {
add();
this.showrecords();
}
// Function of elements Html
this.init = function() {
const btn = builder
.create("button")
.text("Add")
.addEventListener("click", this.addEntry)
.setAttribute("id", "add")
.appendSelector("div")
.build();
const phoneBookContact = builder
.create("div")
.setAttribute("id", "addBook")
.appendSelector("div")
this.showrecords();
};
// Function: Read contacts from the array and display them
this.showrecords = () => {
const addBookId = document.getElementById('addBook');
const index = 0;
addBookId.innerHTML = '';
const arry = phoneBook.records;
arry.forEach(elm => {
// Function of elements Html
const nameContent = builder
.create('li')
.text(`${elm.name}`)
.appendSelector("div>div")
.build();
const phoneContent = builder
.create('li')
.text(`${elm.phone}`)
.appendSelector("div>div")
.build();
});
}
}
const phoneBookContainer = document.getElementById("phone-book-container");
const app = new Render(phoneBookContainer);
app.init();
<form>
<label>Phone Book</label>
<input type="text" placeholder="name" id="name">
<input type="number" placeholder="phone" id="phone">
</form>
<div id="phone-book-container"></div>

How to delete an object from an array in local storage?

I'm creating a kanban board and got stuck in deleting objects from local storage. I've 3 arrays for three kanban columns and they are stored with different keys. I need to delete certain card on click and update the array in local storage.
I already can restore the items and delete the markup on click, but it's still in local storage.
Here's my working code:
var saveToStorage = function (data, key) {
var dataString = JSON.stringify(data);
localStorage.setItem(key, dataString);
};
var getFromStorage = function (key) {
var dataString = localStorage.getItem(key);
return JSON.parse(dataString);
};
var deleteFromList = function (task, list) {
for (var i in list) {
var currentTask = list[i];
if (tasksAreEqual(currentTask, task)){
list.splice(i, 1);
}
}
};
var tasksAreEqual = function (task1, task2) {
var task1Str = JSON.stringify(task1);
var task2Str = JSON.stringify(task2);
return task1Str === task2Str;
};
var createCard = function (task) {
var card = $("<div class = \"card\">");
var cardBody = $("<div class=\"card-body\">");
var cardHeader = $("<div class=\"d-flex justify-content-between align-items-start\">");
var cardText = $("<p class=\"card-text\">").text(task.message);
var btnRemove = $("<button type='button' id='remove' class='btn btn-outline-danger'>").text("x");
var btnNext = $("<button type='button' id='next' class='btn btn-outline-success'>").text("Next =>");
cardHeader.append(cardText, btnRemove);
cardBody.append(cardHeader, btnNext);
card.append(cardBody)
btnRemove.on("click", function(e) {
e.preventDefault();
card.remove();
});
$("#todo").append(card);
};
var todoList = getFromStorage("todo") || [];
var progressList = getFromStorage("progress") || [];
var doneList = getFromStorage("done") || [];
var btnAdd = $("#add-btn");
btnAdd.on("click", function () {
var taskMsg = $("#task-msg").val();
var task = {
message: taskMsg
};
createCard(task);
todoList.push(task);
saveToStorage(todoList, "todo");
});
$(function() {
var todoArr = getFromStorage("todo");
for (var i of todoArr) {
var task = i;
createCard(task);
}
});
Save the list to localStorage when task removed
// added "return list;"
var deleteFromList = function(task, list) {
for (var i in list) {
if (tasksAreEqual(list[i], task)) {
list.splice(i, 1);
}
}
return list;
};
btnRemove.on("click", function(e) {
e.preventDefault();
todoList = deleteFromList(task, todoList);
localStorage.setItem('todo', JSON.stringify(todoList))
card.remove();
});
$(function() {
var todoArr = getFromStorage("todo");
// prevent the error 'TypeError: todoArr is null'
if (!todoArr) return;
for (var i of todoArr) {
var task = i;
createCard(task);
}
});

Sharing object array between controllers while working with modal window in angularJS

I am trying to work with an object array which I am sharing among two controllers one of which is dealing with modal window.
Here is the js code.
angular.module('MyApp', ['ngMaterial', 'ngMessages', 'material.svgAssetsCache', 'ui.bootstrap'])
.service('Faq', function ($http) {
this.faqList = [];
this.faqList = $http.get('/Json/faq.json');
this.getFaqs = function ()
{
return this.faqList;
}
this.addfaq = function (obj) {
this.faqList.push(obj);
};
})
.controller('AppCtrl', function ($scope,$modal,Faq) {
$scope.faqData = [];
Faq.getFaqs().then(function (msg) {
$scope.faqData = msg.data;
});
}
$scope.show = function () {
$modal.open({
templateUrl: "faqAddUpdate.html",
controller: "faqctrl"
});
};
})
.controller('faqctrl', function ($scope, $modalInstance, Faq) {
$scope.question = '';
$scope.id = '';
$scope.answer = '';
$scope.editFaq = function (id) {
$scope.divFaq = true;
$scope.faqs = [];
Faq.getData().then(function (msg) {
$scope.faqs = msg.data;
var l = $scope.faqs.length;
for (var i = 0; i < l; i++) {
if ($scope.faqs[i].id == id) {
$scope.question = $scope.faqs[i].question;
$scope.id = $scope.faqs[i].id;
$scope.answer = $scope.faqs[i].answer;
}
}
});
};
$scope.AddUpdateFAQ = function () {
var faq = {
id: $scope.id,
question: $scope.question,
answer: $scope.answer
};
Faq.addfaq(faq);
console.log(faq);
$modalInstance.close();
};
$scope.Cancel = function () {
$modalInstance.dismiss();
};
});
but when I am submitting the data through the modal it says this.faqList.push is not a function.
It is because your faqList variable is not an array.
You overide the first definition:
this.faqList = [];
With this:
this.faqList = $http.get('/Json/faq.json');
But $http.get returns a promise (see doc), not an array.
You should do something like this:
this.faqList = [];
$http.get('/Json/faq.json').then(function(result) {
// process your results here
this.faqList = result.data;
});
Not tried, but this is within the function scope, so create a _this var first might help:
this.faqList = [];
this.faqList = $http.get('/Json/faq.json');
var _this = this;
this.getFaqs = function ()
{
return _this.faqList;
}
this.addfaq = function (obj) {
_this.faqList.push(obj);
};

issue: dual selectlist moving all items

below code is about dual selectlist. as shown in below image.
Its working as desire. Only problem is, if I click on last subject from Right hand side list box (select Subject list), it is moving all subject to left list box. Technically it should only move the clicked (selected) one subject.
Any suggestion to resolve this?
Code is as following
(function () {
'use strict';
angular
.module("eSchoolSystem")
.directive('multiSelect',['$compile', '$log', multiSelect])
function multiSelect($compile, $log) {
return {
restrict: 'E',
scope: {
name: '#',
selectedModel: '=',
availableModel: '='
},
/*template: '<select id="{{name}}-available" multiple ng-model="availableModel" ng-click="toSelected()" ng-options="a as a.subjectShortName for a in Model.available"></select>\n\n\
<select id="{{name}}-selected" ng-click="toAvailable()" multiple ng-model="selectedModel" ng-options="s as s.subjectShortName for s in Model.selected"></select>',
*/
templateUrl:'app/class/html/dualMultiSelect.html',
compile: function() {
return {
pre: function($scope, $elem, $attr) {
var RefreshSelect = function(original, toFilter) {
var filtered = [];
angular.forEach(original, function(entity) {
var match = false;
for (var i = 0; i < toFilter.length; i++) {
if (toFilter[i]["subjectId"] === entity["subjectId"]) {
match = true;
break;
}
}
if (!match) {
filtered.push(entity);
}
});
return filtered;
};
var RefreshModel = function() {
/*$scope.selectedModel = $scope.Model.selected;*/
$scope.selectedModel = angular.copy($scope.Model.selected);
/*$scope.availableModel = $scope.Model.available;*/
$scope.availableModel = angular.copy($scope.Model.available);
};
var Init = function() {
$scope.Model = {
available: $scope.availableModel,
selected: $scope.selectedModel
};
$scope.selectedModel = [];
$scope.availableModel = [];
$scope.toSelected = function() {
$scope.Model.selected = $scope.Model.selected.concat($scope.availableModel);
$scope.Model.available = RefreshSelect($scope.Model.available, $scope.availableModel);
RefreshModel();
};
$scope.toAvailable = function() {
console.log("in here -x1")
console.log("x3-> " + JSON.stringify($scope.selectedModel))
$scope.Model.available = $scope.Model.available.concat($scope.selectedModel);
$scope.Model.selected = RefreshSelect($scope.Model.selected, $scope.selectedModel);
RefreshModel();
};
};
Init();
}
};
}
};
}
}());
Try to remove RefreshModel function and updating selected values in toSelected and toAvailable:
$scope.toSelected = function() {
$scope.Model.selected = $scope.Model.selected.concat($scope.availableModel);
$scope.Model.available = RefreshSelect($scope.Model.available, $scope.availableModel);
$scope.selectedModel = $scope.availableModel;
$scope.availableModel = [];
};
$scope.toAvailable = function() {
$scope.Model.available = $scope.Model.available.concat($scope.selectedModel);
$scope.Model.selected = RefreshSelect($scope.Model.selected, $scope.selectedModel);
$scope.selectedModel = [];
$scope.availableModel = $scope.selectedModel;
};

Doing a knockout foreach on an observable's sub property

This is my div.
<div id="storyBody" data-bind="foreach: CurrentStory.Paragraphs">
<p data-bind="text: $data">
</p>
</div>
Here is my model:
$(function ()
{
var currentUser = "";
nm.Story = function()
{
this.Paragraphs = ko.observableArray([]);
this.CurrentEditorId = ko.observable();
this.LastEditorId = ko.observable();
};
nm.StoryPreview = function()
{
this.Preview = "";
this.documentId = 0;
};
nm.vm = function ()
{
var UserStoryList = ko.observableArray([]),
CurrentStory = ko.observable(),
GetCurrentStory = function (data) {
nm.getStory(data.documentId, GetCurrentStoryCallback, GetCurrentStoryErrorCallback)
},
GetCurrentStoryCallback = function (data) {
var story = new nm.Story().CurrentEditorId(data.CurrentEditorId)
.LastEditorId(data.LastEditorId);
story.Paragraphs(data.Paragraphs);
CurrentStory(story);
},
GetCurrentStoryErrorCallback = function (data) {
},
LoadUserStoriesList = function() {
nm.getStories(LoadUserStoriesListCallback, LoadUserStoriesListErrorCallback);
},
LoadUserStoriesListCallback = function(data)
{
$.each(data, function (index, value) {
var storyPreview = new nm.StoryPreview();
storyPreview.Preview = value.Preview;
storyPreview.documentId = value.DocumentId;
UserStoryList.push(storyPreview);
});
},
LoadUserStoriesListErrorCallback = function (data)
{
};
return {
UserStoryList: UserStoryList,
CurrentStory: CurrentStory,
LoadUserStoriesList : LoadUserStoriesList,
LoadUserStoriesListCallback: LoadUserStoriesListCallback,
GetCurrentStory: GetCurrentStory
}
}();
nm.vm.LoadUserStoriesList();
ko.applyBindings(nm.vm);
});
Seems like this should work, but it doesn't. Any ideas?
You are missing some parenthesis.
Could you try with:
<div id="storyBody" data-bind="foreach: CurrentStory().Paragraphs">
<p data-bind="text: $data">
</p>
</div>

Categories

Resources