I have a constructor like that
function TodoController() {
this.todoList = [];
this.id = 0;
this.ENTER_KEY = 13;
};
TodoController.prototype = {
todoView: function (todo) {
var controller = todoController.todoList;
console.log('controller', controller);
var item = document.createElement('li');
item.setAttribute('class', 'todoItem');
var inpCheckbox = document.createElement('input');
this.setAttributes(inpCheckbox, { 'type': 'checkbox', 'class' : 'itemList'} );
var lbContent = document.createElement('label');
lbContent.innerHTML = todo.getContent();
var btnRemove = document.createElement('button');
console.log('id', this.id)
this.setAttributes(btnRemove, { 'class': 'remove', 'id' : this.id} );
// btnRemove.setAttribute('id', this.id);
//item append each element
item.appendChild(inpCheckbox);
item.appendChild(lbContent);
item.appendChild(btnRemove);
console.log('item', item);
//ul append each item
document.querySelector('#todoListView').appendChild(item);
},
now I want to create a event to delete the item, it like that
var deleteItem = document.getElementsByClassName('remove')
for(var i = 0; i < deleteItem.length; i++) {
deleteItem[i].addEventListener("click", function() {
console.log('done')
});
}
My problem is I can call the class remove, because it to be create into todoView function. In the jQuery I saw it use delegate method, but I don't know how to use it with javascript. please help me
Related
I watched YouTube video and completed the Todo List using Pure JavaScript. I want to change this code to constructor function. but It's not easy.
Below is the code I wrote. I want to improve this code. but it 's not clear how to fix it.
I think addItemTodo code, it's not bad. but removeItem and completeItem code is not good. I wonder if this is the best or if there are other improvements.
function TodoList(todo) {
this.todo = todo;
}
function UI() {
this.addItemTodo = function(todo) {
var list = document.getElementById('todo');
var item = document.createElement('li');
item.innerText = todo.todo;
var buttons = document.createElement('div');
buttons.classList.add('buttons');
var remove = document.createElement('button');
remove.classList.add('remove');
remove.innerHTML = removeSVG;
remove.addEventListener('click', this.removeItem);
var complete = document.createElement('button');
complete.classList.add('complete');
complete.innerHTML = completeSVG;
complete.addEventListener('click', this.completeItem);
buttons.appendChild(remove);
buttons.appendChild(complete);
item.appendChild(buttons);
list.insertBefore(item, list.childNodes[0]); // 최신 순으로 목록 삽입
};
this.removeItem = function(e) {
console.log(e.target);
var item = this.parentNode.parentNode;
var parent = item.parentNode;
parent.removeChild(item);
};
this.completeItem = function() {
var item = this.parentNode.parentNode;
var parent = item.parentNode;
var id = parent.id;
var target = (id === 'todo') ? document.getElementById('completed') : document.getElementById('todo');
parent.removeChild(item);
target.insertBefore(item, target.childNodes[0]);
};
this.clearFields = function() {
document.getElementById('item').value = "";
}
}
var addBtn = document.getElementById('add');
addBtn.addEventListener('click', function() {
var value = document.getElementById('item').value;
var todoList = new TodoList(value);
var ui = new UI();
if(value) {
ui.addItemTodo(todoList);
ui.clearFields();
} else {
console.log("리스트를 입력해 주세요")
}
});
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);
}
});
someone have any idea how i should modify the payment-lines in the POS,I want to add a type of credit card(like a many2one, I did it) but every time I add a line my option change to the first and also when the order is finished not save the value in pos.order -> statement_id.
enter image description here
here is my code:
function POS_CashRegister (instance, local) {
var pos = instance.point_of_sale;
var _t = instance.web._t;
var QWeb = instance.web.qweb;
var round_pr = instance.web.round_precision
const ParentOrder = pos.Order;
pos.PosModel.prototype.models.push({ //loaded model
model: 'pos.credit.card',
fields: ['id', 'name'],
domain: [['pos_active','=',true]],
loaded: function(self,credit_cards){ //pass parameters
self.credit_cards = credit_cards;
},
});
pos.PaymentScreenWidget = pos.PaymentScreenWidget.extend({
validate_order: function(options) {
var self = this;
var currentOrder = self.pos.get('selectedOrder');
var plines = currentOrder.get('paymentLines').models;
for (var i = 0; i < plines.length; i++) {
if(plines[i].cashregister.journal_id[1] === 'Tarjeta de Credito (PEN)')
{
var value = plines[i].node.firstElementChild.nextElementSibling.nextElementSibling.firstElementChild.value;
plines[i].set_credit_card(parseInt(value));
//console.log(plines[i].node.firstElementChild.nextElementSibling.nextElementSibling.firstElementChild.value);
//plines[i].node
}
}
console.log(currentOrder);
self._super(options);
},
render_paymentline: function (line) {
var self = this;
if(line.cashregister.journal_id[1] !== 'Tarjeta de Credito (PEN)'){
if (line.cashregister.currency[1] !== 'USD') {
return this._super(line);
} else {
var el_html = openerp.qweb.render('Paymentline', {widget: this, line: line});
el_html = _.str.trim(el_html);
var el_node = document.createElement('tbody');
el_node.innerHTML = el_html;
el_node = el_node.childNodes[0];
el_node.line = line;
el_node.querySelector('.paymentline-delete')
.addEventListener('click', this.line_delete_handler);
el_node.addEventListener('click', this.line_click_handler);
var sourceInput = el_node.querySelector('.source-input');
var convertedInput = el_node.querySelector('.converted-input');
sourceInput.addEventListener('keyup', function (event) {
el_node.line.set_usd_amount(event.target.value);
convertedInput.value = el_node.line.get_amount_str();
});
line.node = el_node;
return el_node;
}
}else {
return this._super(line);
}
},
});
pos.Paymentline = pos.Paymentline.extend({
initialize: function(attributes, options) {
this.amount = 0;
this.cashregister = options.cashregister;
this.name = this.cashregister.journal_id[1];
this.selected = false;
this.credit_card = false;
this.pos = options.pos;
},
set_credit_card: function(value){
this.credit_card = value;
this.trigger('change:credit_card',this);
},
get_credit_card: function(){
return this.credit_card;
},
export_as_JSON: function(){
return {
name: instance.web.datetime_to_str(new Date()),
statement_id: this.cashregister.id,
account_id: this.cashregister.account_id[0],
journal_id: this.cashregister.journal_id[0],
amount: this.get_amount(),
credit_card_id: this.get_credit_card(),
};
},
});
}
any suggestions?
You can create 2 journals here too. One for visa and another for master If you don't want that drop down there. Another way is you have to store selected option in a variable and then print that variable in front.
To store selected option initially assigned ids to each values of option and after then while validating order you can get that id of that field and from that id you can get your value. By this way also you can do that.
I have a javascript code that I need to repeat many times with just a slight change:
I need to take the function below and repeat it EXACTLY the same apart from changing info_throbber to video_throbber, then, to map_throbber, then picture_throbber and do tyhese changes only on 2 lines: line 2 and 9)
I don't want to just repeat theses dozens of line one after the other, even if it works. I would like to factorize it.
$(function() {
var $modal_types = $('select#game_info_throbber_modal_types') # FIRST INJECTION HERE
, $li = $modal_types.parent('li')
, $ol = $li.parent('ol')
, $form = $modal_types.closest('form')
, $submit = $form.find('input[type=submit]')
, $add_modal = $('Add Modal')
, $remove_modal = $('Remove Modal')
, $hidden_info_modals = $('input[id=game_info_throbber][type=hidden]') # SECOND INJECTION HERE
;
$add_modal.click(function(e) {
e.preventDefault();
.append($remove_modal.clone(true));
create_info_modal($li.clone());
});
$remove_modal.click(function(e) {
e.preventDefault();
$(this).parent('li').remove();
});
});
Using Loop through an array in JavaScript, here what I tried but it fails:
var i, s, myStringArray = [ "info_throbber", "video_throbbe", "map_throbber", "picture_throbber" ], len = myStringArray.length
for (i=0; i<len; ++i) {
if (i in myStringArray) {
s = myStringArray[i];
// ... do stuff with s ...
$(function() {
var $modal_types = $('select#deal_' + s + '_modal_types')
, $li = $modal_types.parent('li')
, $ol = $li.parent('ol')
, $form = $modal_types.closest('form')
, $submit = $form.find('input[type=submit]')
, $add_modal = $('Add Modal')
, $remove_modal = $('Remove Modal')
, $hidden_info_modals = $('input[id=deal_' + s + '][type=hidden]')
;
$add_modal.click(function(e) {
e.preventDefault();
$(this).closest('li')
.append($remove_modal.clone(true));
create_info_modal($li.clone());
});
$remove_modal.click(function(e) {
e.preventDefault();
$(this).parent('li').remove();
});
};
}
};
The problem is it seems to work but not fully as it did not append on both $add_modal nor does it allow to change values. I don't think it's necessary to understand deeply the complexe code above but the thing is it does not work while when I just put all of the 4 functions one after the other one (first for info_throbber, then video_throbber, and so on...), it works. So me creating an iteraiton through the array should be work.
thanks for yourt help,
You have a JavaScript scope issue. The function within the loop is only using the last i value provided for all iterations of that function. You need to pass the index into the function to make it work correctly.
See this stack question, JavaScript loop variable scope, for more information.
The simplest fix is to wrap your function like so
var i, myStringArray = [ "info_throbber", "video_throbber", "map_throbber", "picture_throbber" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
(function(index) {
var s = myStringArray[index];
// ... do stuff with s ...
$(function() {
var $modal_types = $('select#deal_' + s + '_modal_types')
, $li = $modal_types.parent('li')
, $ol = $li.parent('ol')
, $form = $modal_types.closest('form')
, $submit = $form.find('input[type=submit]')
, $add_modal = $('Add Modal')
, $remove_modal = $('Remove Modal')
, $hidden_info_modals = $('input[id=deal_' + s + '][type=hidden]')
;
$add_modal.click(function(e) {
e.preventDefault();
$(this).closest('li')
.append($remove_modal.clone(true));
create_info_modal($li.clone());
});
$remove_modal.click(function(e) {
e.preventDefault();
$(this).parent('li').remove();
});
$submit.click(function(e) {
var components = JSON.stringify( collect_info_modals() )
;
$ol.find('ol.info_modal').remove();
$modal_types.remove();
$hidden_info_modals.val( components );
});
var modal_types_change = function() {
var $el = $(this)
, $li = $(this).closest('li')
, id = $(this).val()
, $components = $li.find('ol.components')
;
$components.remove();
get_modal_structure(id, $li.find('select') );
};
$modal_types.attr({ id: null, name: null });
$li.remove();
var create_info_modal = function($modal, modal_type_id) {
var $select = $modal_types.clone();
if($modal.find('select').length) { $select = $modal.find('select'); }
$select.val(modal_type_id);
$select.change(modal_types_change);
$modal.prepend($select);
$modal.append($add_modal);
$ol.append($modal);
};
var collect_info_modals = function() {
var $info_modals = $ol.find('ol.components')
, components = []
;
$.each($info_modals, function(_, $info_modal) {
$info_modal = $($info_modal);
var info_modal = {}
, $components = $info_modal.find('li.component input')
, modal_id = $info_modal.parent('li').find('select').val()
;
info_modal['modal_id'] = modal_id;
$.each($components, function(_, component) {
component = $(component);
key = component.attr('name');
val = component.val();
info_modal[key] = val;
component.remove();
});
$info_modal.parent('li').remove();
components.push(info_modal);
});
return components;
};
function get_modal_structure(id, $select) {
// Grab modal structure
var url = '/admin/modal_types/modal_structure?id='+id;
$.getJSON(url, function(modal_structure) {
var $ol = $('<ol class="components">');
modal_structure.forEach(function(component){
$ol.append(build(component));
});
$ol.insertAfter($select);
});
};
function build(component, value) {
value = value || '';
var text_maxlength = 300
, $li = $('<li class="component string input stringish" />')
, $label = $('<label>'+component+'</label>')
, $input = $('<input name="'+component+'" type="text" required="required" maxlength='+text_maxlength+' value="' + value + '"/>')
;
// validations
if(component.match(/^text/)) {
$input.attr('maxlength', text_maxlength);
}
$li
.append($label) // returns the LI NOT THE LABEL
.append($input);
return $li;
};
(function() {
var hidden_info_modals = ($hidden_info_modals.val().length) ? $hidden_info_modals.val() : '[]';
hidden_info_modals = JSON.parse( hidden_info_modals );
hidden_info_modals.forEach(function(info_modal) {
var modal_type_id
, $info_modal = $li.clone(true)
, $ol = $('<ol class="components">');
;
modal_type_id = info_modal['modal_id'];
delete info_modal['modal_id'];
for (var key in info_modal) {
$ol.append(build(key, info_modal[key]));
}
$info_modal.append($ol)
$info_modal.append($remove_modal.clone(true))
create_info_modal($info_modal, modal_type_id);
});
})();
create_info_modal($li.clone(true));
});
})(i);
}
Also, you should remove if (i in myStringArray) as that is only needed when you do a foreach loop over the attributes of an object, not when you are looping over the indexes of an array.
Here is my JavaScript code:
function foo(){
var pagingButtons = document.createElement('div');
for(var j = 0; j < pagingObjects.length; j++ )
{
var pagingBtn = CreateHTMLElement("btnPaging"+j.toString(), "btnPaging", ShowPage, 'button', pagingObjects[j].value);
pagingBtn.setAttribute('data-start', pagingObjects[j].start);
pagingBtn.setAttribute('data-end',pagingObjects[j].end);
pagingButtons.appendChild(pagingBtn);
}
}
pagingArea.appendChild(table).appendChild(pagingButtons);
}
function CreateHTMLElement(id, name, onclick, type, value) {
var HTMLElement = document.createElement('input');
HTMLElement.id = id;
HTMLElement.name = name;
HTMLElement.onclick = onclick;
HTMLElement.type = type;
HTMLElement.value = value;
return HTMLElement;
}
I need to get from pagingArea button with id=btnPaging0.
How can I implement it?
document.getElementById("btnPaging0");