Javascript passing function as object affects scope - javascript

I am passing a function as a parameter and i am loosing scope of certain objects unless the object is in global scope. I want to remove the object from global scope.
Here aliasGrid is in global scope i would like to not have it global. However if i
remove its global scope i cannot access it in deleteAliasName() function under.
Global Scope Declaration
aliasGrid = new AliasGrid();
aliasGrid.initialize();
The issue is at showConfirmationDialog('deleteAliasName', 'noResponseConfirmationDialog',aliasNotificationLabel); i pass the name of two functions as string and they are then executable when the 'yes' and 'no' buttons are clicked on the ConfirmationDialog.
This works fine, however i would like the deleteAliasName() to be a property of the AliasGrid function and be passed as a paremeter on showConfirmationDialog('deleteAliasName', 'noResponseConfirmationDialog',aliasNotificationLabel); and executable when the 'yes' button of the ComfirmationDialog is clicked.
AliasGrid.js
function AliasGrid() {
var aliasData= [];
var aliasNotificationLabel = 'Alias Name';
return {
load: function(){
//create grid
},
add: function(){
//adds record to grid
},
getAliasData: function () {
return this.aliasData;
},
delete: function () {
try {
var aliasNameGrid = dijit.byId('aliasNameGrid');
var deleteAliasNameSelection = aliasNameGrid.selection;
var deleteAliasNameCount = 0;
for (var i in deleteAliasNameSelection) {
deleteAliasNameCount++; }
if (deleteAliasNameCount > 0) {
showConfirmationDialog('deleteAliasName', 'noResponseConfirmationDialog',aliasNotificationLabel);
} else {
showNotificationDialog('okResponseNotificationDialog', 'Select Record(s) For Deletion !', aliasNotificationLabel);
}
} catch (error) {
showNotificationDialog('okResponseNotificationDialog', error, aliasNotificationLabel);
}
}
};
};
Confirmation Dialog
function showConfirmationDialog(yesFunction, noFunction, title) {
var confirmationDialog = new dijit.Dialog({
id: 'deleteGridRecordConfirmationId',
title: "<img src='images/niblogo.png' alt='National Insurance Board'class='loginDialogLogo'/>" + title,
content: '<table style= "width: 300px;">' + '<tr>' + '<th style="text-align:center; padding: 5px" colspan="2"><label> Are Your Sure ? </label></th>' + '</tr>' +
'</table>' +
'<div class="dijitDialogPaneActionBar" style="text-align:center;"><button id= yesBtnId onclick=' + yesFunction + ' >Yes</button><button id=noBtnId onclick=' + noFunction + '("deleteGridRecordConfirmationId")>No</button></div>'
});
confirmationDialog.show();
}
DeleteAliasName
function deleteAliasName() {
try {
var aliasData = aliasGrid.getAliasData();
var aliasStore = new dojo.store.Observable(new dojo.store.Memory({
data: aliasData,
idProperty: "id"
}));
var grid = dijit.byId('aliasNameGrid');
aliasStore.query({}).forEach(function (AliasName) {
if (grid.selection[AliasName.id]) {
aliasStore.remove(AliasName.id);
}
});

function showConfirmationDialog(yesFunction, noFunction, title) {
var confirmationDialog = new dijit.Dialog({
id: 'deleteGridRecordConfirmationId',
title: "<img src='images/niblogo.png' alt='National Insurance Board'class='loginDialogLogo'/>" + title,
content: '<table style= "width: 300px;">' + '<tr>' + '<th style="text-align:center; padding: 5px" colspan="2"><label> Are Your Sure ? </label></th>' + '</tr>' +
'</table>' +
'<div class="dijitDialogPaneActionBar" style="text-align:center;"><button id="yesBtnId">Yes</button><button id="noBtnId">No</button></div>'
});
var dijitDialog = $("div.dijitDialogPaneActionBar");
dijitDialog.children("button#yesBtnId").click(yesFunction);
dijitDialog.children("button#noBtnId").click(function()
{
noFunction("deleteGridRecordConfirmationId");
});
confirmationDialog.show();
}
AliasGrid:
function AliasGrid()
{
var aliasData= [];
var aliasNotificationLabel = 'Alias Name';
var self = this;
self.deleteAliasName = function() {
try {
var aliasData = self.getAliasData();
var aliasStore = new dojo.store.Observable(new dojo.store.Memory({
data: aliasData,
idProperty: "id"
}));
var grid = dijit.byId('aliasNameGrid');
aliasStore.query({}).forEach(function (AliasName) {
if (grid.selection[AliasName.id]) {
aliasStore.remove(AliasName.id);
}
});
}
};
return {
load: function(){
//create grid
},
add: function(){
//adds record to grid
},
delete: function () {
try {
var aliasNameGrid = dijit.byId('aliasNameGrid');
var deleteAliasNameSelection = aliasNameGrid.selection;
var deleteAliasNameCount = 0;
for (var i in deleteAliasNameSelection) {
deleteAliasNameCount++; }
if (deleteAliasNameCount > 0) {
showConfirmationDialog(self.deleteAliasName, 'noResponseConfirmationDialog',aliasNotificationLabel);
} else {
showNotificationDialog(okResponseNotificationDialog, 'Select Record(s) For Deletion !', aliasNotificationLabel);
}
} catch (error) {
showNotificationDialog(okResponseNotificationDialog, error, aliasNotificationLabel);
}
}
};
};

Related

jquery checkbox listener for loop

SOLUTION
https://github.com/Campos696/Attendance/commit/28177ff5cf285e9616faddae74fa6f0288a8667a
i have this javascript file:
https://github.com/Campos696/Attendance/blob/master/js/app.js
and am trying to make it so that the checkboxes created by the bodyView, have click listeners, however right now i can only create a listener for one checkbox at a time, is there any way to improve this?
And whether i check or uncheck it does the same thing(decreases daysMissed).
Here is the relevant part of the code:
var bodyView = {
init: function() {
this.render();
},
render: function() {
var student, i, x;
var schoolDays = octopus.getSchoolDays();
var students = octopus.getStudents();
for(i = 0;i < students.length; i++) {
octopus.setCurrentStudent(students[i]);
var daysMissed = octopus.getDaysMissed();
$('#students').append('<tr class="'+i+'"><td class="name-col">' + students[i].name + '</td></tr>');
for(x = 1;x < schoolDays; x++) {
$('.'+i).append('<td id="check'+i+'" class="attend-col"><input type="checkbox"></td>');
};
$('.'+i).append('<td class="missed-col">'+ daysMissed + '</td>');
};
$(function(){
$('#check0').click(function() {
octopus.setCurrentStudent(students[0]);
if($(this).is(':checked')){
octopus.incrementDaysMissed();
} else if(!$(this).is(':checked')){
octopus.decreaseDaysMissed();
}
})
})
}
}
FUNCTION EDIT
$(function(){
$('[id^=check] :checkbox').on('change', function(e) {
var daysMissed = $(this).closest('tr').find('td:last');
if (this.checked) {
octopus.decreaseDaysMissed();
daysMissed.html(octopus.getDaysMissed());
} else {
octopus.incrementDaysMissed();
daysMissed.html(octopus.getDaysMissed());
}
})
})
IDs must be unique. That means you need to change the following line:
$('.'+i).append('<td id="check'+i+'" class="attend-col"><input type="checkbox"></td>');
with:
$('.'+i).append('<td id="check'+ i + x +'" class="attend-col"><input type="checkbox"></td>');
^^^^^^^^
In this way each td has an id like: check01.....check46...
Second issue: change the click event with the change event and attach it to:
$('[id^=check] :checkbox').on('change', function(e) {
select each td having an id starting with check and for each td get the child checkbox.
var model = {
currentStudent: null,
schoolDays: 12,
students: [
{
name: "Slappy the Frog",
daysMissed: 12
},
{
name: "Lilly the Lizard",
daysMissed: 12
},
{
name: "Paulrus the Walrus",
daysMissed: 12
},
{
name: "Gregory the Goat",
daysMissed: 12
},
{
name: "Adam the Anaconda",
daysMissed: 12
}
]
};
// Octopus
var octopus = {
init: function () {
model.currentStudent = model.students[0];
headerView.init();
bodyView.init();
},
getStudents: function () {
return model.students;
},
setCurrentStudent: function (student) {
model.currentStudent = student;
},
getSchoolDays: function () {
return model.schoolDays + 1;
},
getDaysMissed: function () {
return model.currentStudent.daysMissed;
},
incrementDaysMissed: function () {
model.currentStudent.daysMissed++;
},
decreaseDaysMissed: function () {
model.currentStudent.daysMissed--;
}
};
// View
var headerView = {
init: function () {
this.render();
},
render: function () {
var i;
var schoolDays = octopus.getSchoolDays();
$('#header').append('<th class="name-col">Student Name</th>');
for (i = 1; i < schoolDays; i++) {
$('#header').append('<th>' + i + '</th>');
}
;
$('#header').append('<th class="missed-col">Days Missed</th>');
}
};
var bodyView = {
init: function () {
this.render();
},
render: function () {
var student, i, x;
var schoolDays = octopus.getSchoolDays();
var students = octopus.getStudents();
$('#students').empty();
for (i = 0; i < students.length; i++) {
octopus.setCurrentStudent(students[i]);
var daysMissed = octopus.getDaysMissed();
$('#students').append('<tr class="' + i + '"><td class="name-col">' + students[i].name + '</td></tr>');
for (x = 1; x < schoolDays; x++) {
$('.' + i).append('<td id="check' + i + x + '" class="attend-col"><input type="checkbox"></td>');
}
$('.' + i).append('<td class="missed-col">' + daysMissed + '</td>');
}
$(function(){
$('[id^=check] :checkbox').on('change', function(e) {
var colId = $(this).closest('td').index();
var rowId = $(this).closest('tr').index();
var studentName =
$(this).closest('tr').find('td:first').text();
console.log('Student: <' + studentName +
'> on day: ' + colId + ' changed to: ' +
this.checked + ' Col: ' + colId + ' Row: ' + rowId);
})
})
}
}
$(function () {
octopus.init();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://rawgit.com/Campos696/Attendance/master/css/style.css">
<h1>Udacity Attendance</h1>
<table>
<thead>
<tr id="header"></tr>
</thead>
<tbody id="students"></tbody>
</table>
Use the input:checkbox selector to get all checkboxes:
$(function(){
$("input:checkbox").click(function() {
octopus.setCurrentStudent(students[0]);
if($(this).prop("checked",true)){
octopus.incrementDaysMissed();
} else {
octopus.decreaseDaysMissed();
}
});
});

delete from database with javascript

I added a delete function to a todo list app that i built. The delete function works; however, when I refresh the page all the items that i deleted come back. How can I remove the items permanently from the database?
$(function() {
// The taskHtml method takes in a JavaScript representation
// of the task and produces an HTML representation using
// <li> tags
function taskHtml(task) {
var checkedStatus = task.done ? "checked" : "";
var liClass = task.done ? "completed" : "";
var liElement = '<li id="listItem-' + task.id +'" class="' + liClass + '">' +
'<div class="view"><input class="toggle" type="checkbox"' +
" data-id='" + task.id + "'" +
checkedStatus +
'><label>' +
task.title +
// '<button class="deletebutton" type="button">Delete</button>' +
'</label></div></li>';
return liElement;
}
// toggleTask takes in an HTML representation of the
// an event that fires from an HTML representation of
// the toggle checkbox and performs an API request to toggle
// the value of the `done` field
function toggleTask(e) {
var itemId = $(e.target).data("id");
var doneValue = Boolean($(e.target).is(':checked'));
$.post("/tasks/" + itemId, {
_method: "PUT",
task: {
done: doneValue
}
}).success(function(data) {
var liHtml = taskHtml(data);
var $li = $("#listItem-" + data.id);
$li.replaceWith(liHtml);
$('.toggle').change(toggleTask);
} );
}
$.get("/tasks").success( function( data ) {
var htmlString = "";
$.each(data, function(index, task) {
htmlString += taskHtml(task);
});
var ulTodos = $('.todo-list');
ulTodos.html(htmlString);
$('.toggle').change(toggleTask);
});
$('#new-form').submit(function(event) {
event.preventDefault();
var textbox = $('.new-todo');
var payload = {
task: {
title: textbox.val()
}
};
$.post("/tasks", payload).success(function(data) {
var htmlString = taskHtml(data);
var ulTodos = $('.todo-list');
ulTodos.append(htmlString);
$('.toggle').click(toggleTask);
$('.new-todo').val('');
});
});
//////this section works
$("#deletebutton").on("click", function() {
$(".todo-list li.completed").remove()
///////this does not want to remove the item from the database
$.destroy("/tasks/" + itemId, {
_method: "destroy",
task: {
done: doneValue
}
});
});
$(function() {
// The taskHtml method takes in a JavaScript representation
// of the task and produces an HTML representation using
// <li> tags
function taskHtml(task) {
var checkedStatus = task.done ? "checked" : "";
var liClass = task.done ? "completed" : "";
var liElement = '<li id="listItem-' + task.id +'" class="' + liClass + '">' +
'<div class="view"><input class="toggle" type="checkbox"' +
" data-id='" + task.id + "'" +
checkedStatus +
'><label>' +
task.title +
// '<button class="deletebutton" type="button">Delete</button>' +
'</label></div></li>';
return liElement;
}
// toggleTask takes in an HTML representation of the
// an event that fires from an HTML representation of
// the toggle checkbox and performs an API request to toggle
// the value of the `done` field
function toggleTask(e) {
var itemId = $(e.target).data("id");
var doneValue = Boolean($(e.target).is(':checked'));
// still dont understand this
$.post("/tasks/" + itemId, {
_method: "PUT",
task: {
done: doneValue
}
}).success(function(data) {
var liHtml = taskHtml(data);
var $li = $("#listItem-" + data.id);
$li.replaceWith(liHtml);
$('.toggle').change(toggleTask);
} );
}
$.get("/tasks").success( function( data ) {
var htmlString = "";
$.each(data, function(index, task) {
htmlString += taskHtml(task);
});
var ulTodos = $('.todo-list');
ulTodos.html(htmlString);
$('.toggle').change(toggleTask);
});
$('#new-form').submit(function(event) {
event.preventDefault();
var textbox = $('.new-todo');
var payload = {
task: {
title: textbox.val()
}
};
$.post("/tasks", payload).success(function(data) {
var htmlString = taskHtml(data);
var ulTodos = $('.todo-list');
ulTodos.append(htmlString);
$('.toggle').click(toggleTask);
$('.new-todo').val('');
});
});
$("#deletebutton").on("click", function() {
$(".todo-list li.completed").remove()
var li_to_delete = $('.todo-list li.completed');
$.ajax({
type: 'DELETE',
url: "/tasks" + li_to_delete,
success: function(){
li_to_delete.remove();
}
});
});
});
i changed the code but im not sure how to properly extract the url.

Adding event to multiple buttons in Dojo

I'm listing my products like in the following image.
I want to add delete event to my delete buttons.
My product card html creator function looks like this.
getCardSummaryView: function(card) {
var html = "";
html += "</br>";
html += "<div>";
html += "<label>Product Name: " + card.Product.Name + "</label></br>";
html += "<button id='deleteCard" + card.Product.Id + "'>Delete</button>";
html += "</div>";
return html;
}
array.forEach(response.products, function (item) {
var view = this.getCardSummaryView(item);
dom.byId("sideBar").innerHTML += view;
var node = dom.byId("deleteCard" + item.Id);
on(node, "click", function (e) {alert("something");})
}
But if I add 3 product to panel, only last button click is populating, others doesn't work.
What am I doing wrong?
I believe the following line is problematic because on each iteration, you're rebuilding the DOM and destroying all the event listeners that you just added.
dom.byId("sideBar").innerHTML += view;
You can simply appendChild instead.
http://jsfiddle.net/rayotte/8uRXe/356/
require([
"dojo/_base/array"
, "dojo/dom"
, "dojo/dom-construct"
, "dojo/on"
, "dojo/domReady!"
], function (
array
, dom
, domConstruct
, on
) {
var getCardSummaryView = function (product) {
var html = "";
html += "<br/>";
html += "<div>";
html += "<label>Product Name: " + product.Name + "</label><br/>";
html += "<button type='button' id='deleteCard" + product.Id + "'>Delete</button>";
html += "</div>";
return html;
}
var products = [
{
Id: 1
, Name: 'Product 1'
}
,{
Id: 2
, Name: 'Product 2'
}
,{
Id: 3
, Name: 'Product 3'
}
]
var sideBarNode = dom.byId("sideBar");
array.forEach(products, function (product) {
sideBarNode.appendChild(domConstruct.toDom(getCardSummaryView(product)));
on(dom.byId("deleteCard" + product.Id), 'click', function(e){
console.log('testing' + product.Id)
})
});
});
If i Where You i would do it this way because while you can see the buttons is created but that doesn't mean you can listen to them at that point so I will attach the buttons after the loop is done.
require(["dojo/_base/array","dijit/form/ValidationTextBox",
"dijit/form/Button","dojo/dom","dojo/on","dojo/domReady!"], function(array,ValidationTextBox,Button,dom,on){
var getCardSummaryView = function(card) {
var html = "";
html += "</br>";
html += "<div>";
html += "<label>Product Name: " + card.Product.Name + "</label></br>";
html += "<button id='deleteCard" + card.Product.Id + "'>Delete</button>";
html += "</div>";
return html;
}
var objectvalue = {};
var arrayvalue = new Array();
objectvalue.Product = {};
objectvalue.Product.Name = "hello1";
objectvalue.Product.Id = "ThisisWhy1";
arrayvalue.push(objectvalue);
var test = {};
test.Product = {};
test.Product.Name = "hello2";
test.Product.Id = "ThisisWhy2";
arrayvalue.push(test);
var test2 = {};
test2.Product = {};
test2.Product.Name = "hello3";
test2.Product.Id = "ThisisWhy3";
arrayvalue.push(test2);
array.forEach(arrayvalue, function (item) {
var view = getCardSummaryView(item);
dom.byId("sideBar").innerHTML += "----------------"
dom.byId("sideBar").innerHTML += view;
var node = dom.byId("deleteCard" + item.Product.Id);
});
var myButton = new Button({
label: "Click me!",
onClick: function(){
alert("1");
}
}, "deleteCard" + "ThisisWhy1");
var myButton = new Button({
label: "Click me!",
onClick: function(){
alert("2");
}
}, "deleteCard" + "ThisisWhy2");
var myButton = new Button({
label: "Click me!",
onClick: function(){
alert("3");
}
}, "deleteCard" + "ThisisWhy3");
});
ofcourse you can loop through the buttons when creating them but just to elaborate i created three instances
Click HERE to see the working in jsfiddle.

multiple onload error in HTML

HTML:-
In the body tag I have used onload="variable2.init() ; variable1.init();".
JavaScript:-
var variable1 = {
rssUrl: 'http://feeds.feedburner.com/football-italia/pAjS',
init: function() {
this.getRSS();
},
getRSS: function() {
jQuery.getFeed({
url: variable1.rssUrl,
success: function showFeed(feed) {
variable1.parseRSS(feed);
}
});
},
parseRSS: function(feed) {
var main = '';
var posts = '';
var className = 'even';
var pst = {};
for (i = 0; i < feed.items.length; i++) {
pst = variable1.parsefootballitaliaRSS(feed.items[i]);
if (className == 'odd') {
className = 'even';
}
else {
className = 'odd';
}
var shorter = pst.story.replace(/<(?:.|\n)*?>/gm, '');
item_date = new Date(feed.items[i].updated);
main += '<div id="content1" class="post-main ' + className + '" onclick="mwl.setGroupTarget(\'#screens1\', \'#blog_posts1\', \'ui-show\', \'ui-hide\');mwl.setGroupTarget(\'#blog_posts1\', \'#post' + (i+1) + '\', \'ui-show\', \'ui-hide\');">';
main += '<b>' + pst.title.trunc(55, true) + '</b><br />' + shorter.trunc(30, true);
main += '<div class="datetime">' + item_date.getDateTime() + '</div></div>';
posts += '<div class="post-wrapper ui-hide" id="post' + (i+1) + '">';
posts += '<div class="post-title"><b>' + pst.title + '</b></div>';
posts += feed.items[i].description;
posts += '</div>';
}
jQuery('#main_screen1').html(main);
jQuery('#blog_posts1').html(posts);
},
parsefootballitaliaRSS: function(item) {
var match = item.description.match('src="([^"]+)"');
var part = item.description.split('<font size="-1">');
var arr = {
title: item.title,
link: item.link,
image: match,
site_title: item.title,
story: item.description
};
return arr;
}
};
var variable2 = {
weatherRSS: 'http://feeds.feedburner.com/go/ELkW',
init: function() {
this.getWeatherRSS();
},
getWeatherRSS: function() {
jQuery.getFeed({
url: variable2.weatherRSS,
success: function showFeed(feed) {
variable2.parseWeather(feed);
}
});
},
parseWeather: function(feed) {
var main = '';
var posts = '';
var className = 'even';
var pst = {};
for (i = 0; i < feed.items.length; i++) {
pst = variable2.parsegoRSS(feed.items[i]);
if (className == 'odd') {
className = 'even';
}
else {
className = 'odd';
}
var shorter = pst.story.replace(/<(?:.|\n)*?>/gm, '');
item_date = new Date(feed.items[i].updated);
main += '<div id="content2" class="post-main ' + className + '" onclick="mwl.setGroupTarget(\'#screens2\', \'#blog_posts2\', \'ui-show\', \'ui-hide\');mwl.setGroupTarget(\'#blog_posts2\', \'#post' + (i+1) + '\', \'ui-show\', \'ui-hide\');">';
main += '<b>' + pst.title.trunc(55, true) + '</b><br />' + shorter.trunc(30, true);
main += '<div class="datetime">' + item_date.getDateTime() + '</div></div>';
posts += '<div class="post-wrapper ui-hide" id="post' + (i+1) + '">';
posts += '<div class="post-title"><b>' + pst.title + '</b></div>';
posts += feed.items[i].description;
posts += '</div>';
}
jQuery('#main_screen2').html(main);
jQuery('#blog_posts2').html(posts);
},
parsegoRSS: function(item) {
var match = item.description.match('src="([^"]+)"');
var part = item.description.split('<font size="-1">');
var arr = {
title: item.title,
link: item.link,
image: match,
site_title: item.title,
story: item.description
};
return arr;
}
};
When I run the program it only reads one of the variables i.e. either 1 or 2.
How can I correct them to read both the variables?
Use this.
<script type="text/javascript">
window.onload = function() {
variable1.init();
variable2.init();
}
</script>
Try this
<body onload="callFunctions()">
JS-
function callFunctions()
{
variable1.init();
variable2.init();
}
Update-
Also
there are other different ways to call multiple functions on page load
Hope it hepls you.

Placing a div only after clicked object

Buildgames returns rows:
<a>....</a>
<a>....</a>
When I click on each a the Buildcar_s function returns all the data inside an alert.
Instead of this alert I want to put all the results in a div under each a, so it would look like:
<a>.....clicked ...</a>
<div>....
...
</div>
<a>....not clicked...</a>
<a>....not clicked...</a>
<a>....not clicked...</a>
How can we put a div only under the a which was clicked?
function Buildcar_s(items) {
var div = $('<div/>');
$.each(items, function() {
var car_ = this.car_;
$('<a>' + this.car_ + '----' + this.Names + '---' + '</a>').click(function() {
_Services.invoke({
method: 'GetgamesRows',
data: {
car_Number: car_
},
success: function(car_s) {
var div = Buildgames(car_s);
$(div).insertAfter($a);
}
});
}).appendTo(div);
$('<br/>').appendTo(div);
});
$("#leftRows").append(div);
}
function Buildgames(items) {
var place = '<div>';
$.each(items, function() {
place += 'mmmmmm<br/>';
});
place += '</div>';
return place;
}
Try this, relevant changes have been commented:
function Buildcar_s(items) {
var div = $('<div/>');
$.each(items, function() {
var car_ = this.car_;
$('<a>' + this.car_ + '----' + this.Names + '---' + '</a>').click(function() {
var $a = this;
_Services.invoke({
method: 'GetgamesRows',
data: {
car_Number: car_
},
success: function(car_s) {
var div = Buildgames(car_s);
// this inserts the HTML generated from the function,
// under the A element which was clicked on.
$(div).insertAfter($a);
}
});
}).appendTo(div);
$('<br/>').appendTo(div);
});
$("#leftRows").append(div);
}
function Buildgames(items) {
var place = '<div>';
$.each(items, function() {
place += '<div style="float: right;"> ' + this.CITY + ' ' + '</div><BR />' + +'<br/><br/>';
});
place += '</div>';
return place; // returns the string created, as opposed to alerting it.
}

Categories

Resources