I am facing a weird issue with "this". I have the code as follow which is for a page. In this I am creating a page and binding the onclick events. Here I reset the self[key] everytime I call funcOne but onClick I am setting the data.
The second time when I call funcOne and again I call onClick the data in this[key] is the old data instead of resetting.
Please suggest if I am doing anything wrong here. I am new to Javascript.
classExample = function(page) {
someBaseClass.call(this, page);
}
classExample.prototype.funcOne = function() {
var self = this;
var callback = function(data) {
self[key] = []; //based on some logic I am setting
};
model.getData(callback);
someButton.onClick = function() {
self.funcTwo();
};
};
classExample.prototype.funcTwo = function() {
//function from other class is called and data to this[key] is set
classTwo.someMethod(this);
var savedData = this[key];
};
var obj = new classExample(page);
obj.funcOne();
//after this I invoke onClick event
PS : I am not using any third party library.
Related
i've node app and I've created a module/file to restore some global value via event that update the value and return it, when I use it I always get false even the event was called,How I can do it right ?
I want it to behave like getter property,
global.js file
var inter = require("../pl/intr");
var isAvailable;
inter.eventEmitter.on('AppAvailable', function () {
console.log("---events is raised--");
isAvailable = true;
});
module.exports = {
isAvailable:isAppAvailable
}
I checked the event and the console.log was called...
Does this do what you need?
var inter = require("../pl/intr");
module.exports = {isAvaiable:false};
inter.eventEmitter.on('AppAvailable', function () {
console.log("---events is raised--");
module.exports.isAvailable = true;
});
I really need help with an aspect of my project. My ultimate goal is to capture the changes made by a user and once they select confirm, post it to SQL for updating. I will use AJAX and PHP for the latter part of the project but I thought JSON would be a great idea to hold all the changes made by a user (the first part).
I am new to JSON and I'm having trouble putting the results in one large object that will be transferred to the server when the user selects "OK". Can someone help me with the coding of this? Is JSON the best way to accomplish the goal (of storing temporary?
Heres what I have so far (just a snippet):
HTML
<div class="button" data-info='2' data-id='8-7' onclick=addDeskid(e)></div>
<div class="button" data-info='4' data-id='2-5' onclick=remDeskId()></div>
<div class="button" value="submit">submit</div>
JS
function addDeskId(e){
$adjustment;
userObject = $(this);
userObjectChange = 'CHANGE_SEAT_TO'; //This is what i will use with AJAX and PHP to determine the SQL statement
userObjectID = userObject.attr('data-info'); //This is the unique SQL ID for the object being modified
userObjectDeskID = userObject.attr('data-id'); //This is the attribute for the object being modified
userObjectSeatID = 9-4; //This is what the attribute is being modified to, for the question, ill make it a solid value
var addUserObject = new jsonAddTest(userObjectID, userObjectChange, userObjectDeskID, userObjectSeatID,);
//this is what the function is actually doing on the user side
//$dragObject.attr("data-id",newSeat); //change desk number for new user location
//$dragObject.attr("previousseat", "T");
//var extPass = e;
//moveOrSetupAccountLog(extPass);
}
function remDeskId(){
userObject = $dropObject.find('div.dragTest');
userObjectChange = 'REMOVESEAT'; //This is what i will use with AJAX and PHP to determine the SQL statement
userObjectID = userObject.attr('data-info'); //This is the unique SQL ID for the object being modified
userObjectDeskID = userObject.attr('data-id'); //This is the attribute for the object being modified
userObjectDeskIDVal = 0; //This is what the attribute is being modified to
var remUserObject = new jsonRemTest(userObjectID, userObjectChange, userObjectDeskID, userObjectDeskIDVal);
//this is what the function is actually doing on the user side
//userObject.attr({"data-id":""}); //remove desk number for new user location
//userObject.appendTo('#userPool');
}
//JSON functions test
function jsonRemTest(id, change, name, seat, value){
this.ID = id;
this.ChangeType = change;
this.Name = name;
this.Seat = seat;
this.setTo = value;
userMoves.push(jsonRemTest);
}
function jsonAddTest(id, change, name, desk, seat, previousseat, previousseatnewvalue){
this.ID = id;
this.ChangeType = change;
this.Name = name;
this.Seat = desk;
this.setTo = seat;
this.PreviousSeatValue = previousseat;
this.PreviousSeatNewValue = previousseatnewvalue;
userMoves.push(jsonAddTest);
}
console.log(JSON.stringify(userMoves));
I am getting the error: userMoves is undefined. I understand why this is happening but I don't know how to correct it.
TL;DR
Every time the user clicks on this button, it generates an array. I want to combine all the arrays into one object that contains all of them. When the user clicks on a submit button, the object is sent to the server using AJAX/PHP. Is this the best way to do this and if so, how do I combine the output of the JSON functions into one object in preparation for sending?
Thanks in advance
OK, Let's tackle this with some recommendations.
First off your onclick=addDeskid(e) is not properly cased to call your function and well, it is in the markup not the code, so let's address that.
I also changed your markup slightly to work with my event handlers better using a class for myAddButton and myRemButton, do what you will with that but I used it. I also added a button to get the results logged after all the events fired. This is the reason you get [] you have nothing in there when it gets logged. I did nothing with the submit, that is yours to handle (ajax call?)
<div class="button myAddButton" data-info='2' data-id='8-7'>add</div>
<div class="button myRemButton" data-info='4' data-id='2-5'>remove</div>
<div class="button mySubmitButton">submit</div>
<button id="ShowResults" type='button'>ShowResults</button>
Now the code - I re-engineered this to create a "class" for the object using makeClass. This is just one way but does allow for instance objects when needed and makes it easier to namespace some functions. I artificially put a private function in there just to demonstrate use as well as a public function. Note the the "this" inside that function is the instance object NOT a global object. (google makeClass with the attributed authors for more info)
I created a "class" with generic attributes. You COULD create different functions for "add" and "remove" instead of the SetChangeObject function - like one for each...I used a generic one so the "object" has the same signature.
Now the code: this is definitely a bit artificial in some places just to demonstrate use:
// makeClass - By Hubert Kauker (MIT Licensed)
// original by John Resig (MIT Licensed).
function makeClass() {
var isInternal;
return function (args) {
if (this instanceof arguments.callee) {
if (typeof this.init == "function") {
this.init.apply(this, isInternal ? args : arguments);
}
} else {
isInternal = true;
var instance = new arguments.callee(arguments);
isInternal = false;
return instance;
}
};
}
var SeatGroup = makeClass(); //create our class
//the method that gets called on creation instance object of class
SeatGroup.prototype.init = function (id, changeType, name, desk, seat, setToValue, previousseat, previousseatnewvalue) {
// a default value
var defaultSeat = "default";
var defaultName = "default";
this.ID = id;
this.ChangeType = changeType;
this.Name = name ? name : defaultName;
this.Desk = desk ? desk : "";
this.Seat = seat ? seat : privateFunction(defaultSeat);;
this.SetTo = setToValue ? setToValue : this.ID;
this.PreviousSeatValue = previousseat ? previousseat : "";
this.PreviousSeatNewValue = previousseatnewvalue ? previousseatnewvalue : "";
this.changeObject = {};
// public method
this.SetChangeObject = function () {
this.changeObject.ID = this.ID;
this.changeObject.ChangeType = this.ChangeType;
this.changeObject.Name = this.Name;
this.changeObject.Seat = this.Seat;
this.changeObject.Desk = this.Desk;
this.changeObject.SetTo = this.SetTo;
this.changeObject.PreviousSeatValue = this.PreviousSeatValue;
this.changeObject.PreviousSeatNewValue = this.PreviousSeatNewValue;
};
function privateFunction(name) {
return name + "Seat";
}
};
var userMoves = [];//global warning-global object!!
//event handlers
$('.myAddButton').on('click', addDeskId);
$('.myRemButton').on('click', remDeskId);
$('#ShowResults').on('click', function () {
console.log(JSON.stringify(userMoves));//log this after all are pushed
});
//function called with the "add" that can be customized
function addDeskId(e) {
var uo = $(this);//jQuery of the "myAddButton" element
var userObjectChange = 'CHANGE_SEAT_TO';
var userObjectID = uo.data('info');
var userObjectDeskID = uo.data('id');
var userObjectSeatID = '9-4';
// create a private instance of our class (calls init function)
var uChange = SeatGroup(userObjectID, userObjectChange, userObjectDeskID, userObjectSeatID);
uChange.SetChangeObject();//call public function
//log what we created
console.dir(uChange.changeObject);
//does not work, its private: console.log( uChange.privateFunction('hi'));
// push to our global
userMoves.push(uChange.changeObject);
}
// event function, customize as needed
function remDeskId() {
var userObject = $(this);
var userObjectChange = 'REMOVESEAT';
var userObjectID = userObject.data('info');//use jQuery data, easier/better
var userObjectDeskID = userObject.data('id');
var userObjectDeskIDVal = 0;
var remUserObject = SeatGroup(userObjectID, userObjectChange, userObjectDeskID);
remUserObject.PreviousSeatValue = "FreddySeat";//show how we set a properly of our object
remUserObject.SetChangeObject();//call public function
console.dir(remUserObject.changeObject);
userMoves.push(remUserObject.changeObject);
}
Play around with it here: http://jsfiddle.net/q43cp0vd/1/
What I want to achieve is to create subscription for model properties. This subscription function should call WebApi via Ajax updating property value in database. For ajax call I need three paramaters: "fieldName", "fieldValue" and "modelId", ajax will update database row based on those three parameters.
I have many properties and all of them need the same functionality, so I do not want to subscribe for each property individually, so I found a following suggestion:
ko.subscribable.fn.withUpdater = function (handler) {
var self = this;
this.subscribe(handler);
//support chaining
return this;
};
Add this is how it is "attached" to observables:
self.ModelId= ko.observable();
self.CompanyName = ko.observable().withUpdater(update);
where update is some js function outside model.
However, I have problem, because I am not able to pass three paramaters to update functions (or also I can say in another words - I need to be able to get viewModel.ModelId property value inside update, as well as propertyName).
function update (propertyName, propertyNewValue, anotherPropertyValue) {
//do ajax update
}
As an example for CompanyName property it will be:
update("CompanyName", "New Company value here", 3),
where
3 == viewModel.ModelId
There might be a better way to do this, but the following will work:
First, add a target object to the withUpdate method:
ko.subscribable.fn.withUpdater = function (handler, target, propname) {
var self = this;
var _oldValue;
this.subscribe(function (oldValue) {
_oldValue = oldValue;
}, null, 'beforeChange');
this.subscribe(function (newValue) {
handler.call(target, _oldValue, newValue, propname);
});
return this;
};
The update subscribe function will get scoped to the target property:
var update = function (propertyName) {
console.log('propname is '+ propname + ' old val: ' + oldvalue + ', new val: ' + newvalue + ', model id: ' + this.ModelId());
}
Now you will need to use it a little differently.
self.CompanyName = ko.observable().withUpdater(update, self, "CompanyName");
An example http://plnkr.co/edit/HhbKEm?p=preview
I couldn't get the scope of the withUpdater function to be that of the object without explicitly passing in the target and a string for the company name.
You can declare your function as a variable outside of the 'fn' scope.
var dataservice = 'my class that has the data calls';
var altFunc = function () {
return ko.pureComputed(function () {
var currentItem = this().filter(function (item) {
// Do knockout stuff here and return your data
// also make calls to the dataservice class
}, this, dataservice);
};
ko.observableArray.fn.someNewFunctionality = altFunc;
I'd like to create an event for each function in a script, then inject the event trigger into the end of the function.
This way I can see exactly when each function has completed and use the events like hooks for other functions
If I can do it dynamically, I can add as many new functions as I like without having to create and append these events.
Here's a basic example of what I'm trying to do, this won't actually work, but it gives you an idea. I have been using jQuery, but I'll accept any JavaScript framework at all, and any method.
var obj = {};
(function()
{
this.init = function()
{
// loop through every function
$.each(this, function(k, v)
{
// create an event for every function
$('body').bind(v, function()
{
console.log('Event: ' + v + ' Finished');
});
// Add a event trigger into each specific function in the loop
this[v].call($('body').trigger(v));
});
}
this.another_function = function()
{
// do something
}
this.some_function = function()
{
/do something
}
}).apply(obj);
obj.init();
(edit) The script itself basically renders a Calendar, but there are a lot of callbacks, ajax requests, buttons. etc... If I could tie each feature down to an event, it would make my life easier when extending it, adding new features etc...
Loop through every function, replace it with new one, which calls original function on the same object and triggers event on body.
var obj = { };
(function()
{
this.init = function()
{
var self = this;
foreach(var name in this) {
if (typeof k !== 'Function') continue;
if (name ==='init') continue;
var original = this[name];
var newFunc = function() {
original.apply(self, arguments);
$('body').trigger(name);
}
this[name] = newFunc;
}
}
this.another_function = function()
{
// do something
}
this.some_function = function()
{
/do something
}
}).apply(obj);
obj.init();
I just started using javascript and I'm missing something important in my knowledge. I was hoping you could help me fill in the gap.
So the script I'm trying to run is suppose to count the characters in a text field, and update a paragraph to tell the user how many characters they have typed. I have an object called charCounter. sourceId is the id of the text area to count characters in. statusId is the id of the paragraph to update everytime a key is pressed.
function charCounter(sourceId, statusId) {
this.sourceId = sourceId;
this.statusId = statusId;
this.count = 0;
}
There is one method called updateAll. It updates the count of characters and updates the paragraph.
charCounter.prototype.updateAll = function() {
//get the character count;
//change the paragraph;
}
I have a start function that is called when the window loads.
function start() {
//This is the problem
document.getElementbyId('mytextfield').onkeydown = myCounter.updateAll;
document.getElementbyId('mytextfield').onkeyup = myCounter.updateAll;
}
myCounter = new charCounter("mytextfield","charcount");
window.onload = start;
The above code is the problem. Why in the world can't I call the myCounter.updateAll method when the event is fired? This is really confusing to me. I understand that if you call a method likeThis() you'll get a value from the function. If you call it likeThis you are getting a pointer to a function. I'm pointing my event to a function. I've also tried calling the function straight up and it works just fine, but it will not work when the event is fired.
What am I missing?
Thanks for all the answers. Here's three different implementations.
Implementation 1
function CharCounter(sourceId, statusId) {
this.sourceId = sourceId;
this.statusId = statusId;
this.count = 0;
};
CharCounter.prototype.updateAll = function() {
this.count = document.getElementById(this.sourceId).value.length;
document.getElementById(this.statusId).innerHTML = "There are "+this.count+" charactors";
};
function start() {
myCharCounter.updateAll();
document.getElementById('mytextfield').onkeyup = function() { myCharCounter.updateAll(); };
document.getElementById('mytextfield').onkeydown = function() { myCharCounter.updateAll(); };
};
myCharCounter = new CharCounter('mytextfield','charcount');
window.onload = start;
Implementation 2
function CharCounter(sourceId, statusId) {
this.sourceId = sourceId;
this.statusId = statusId;
this.count = 0;
};
CharCounter.prototype.updateAll = function() {
this.count = document.getElementById(this.sourceId).value.length;
document.getElementById(this.statusId).innerHTML = "There are "+ this.count+" charactors";
};
CharCounter.prototype.start = function() {
var instance = this;
instance.updateAll();
document.getElementById(this.sourceId).onkeyup = function() {
instance.updateAll();
};
document.getElementById(this.sourceId).onkeydown = function() {
instance.updateAll();
};
};
window.onload = function() {
var myCounter = new CharCounter("mytextfield","charcount");
myCounter.start();
};
Implementation 3
function CharCounter(sourceId, statusId) {
this.sourceId = sourceId;
this.statusId = statusId;
this.count = 0;
};
CharCounter.prototype.updateAll = function() {
this.count = document.getElementById(this.sourceId).value.length;
document.getElementById(this.statusId).innerHTML = "There are "+this.count+" charactors";
};
function bind(funcToCall, desiredThisValue) {
return function() { funcToCall.apply(desiredThisValue); };
};
function start() {
myCharCounter.updateAll();
document.getElementById('mytextfield').onkeyup = bind(myCharCounter.updateAll, myCharCounter);
document.getElementById('mytextfield').onkeydown = bind(myCharCounter.updateAll, myCharCounter);
};
myCharCounter = new CharCounter('mytextfield','charcount');
window.onload = start;
I think you are having problems accessing your instance members on the updateAll function, since you are using it as an event handler, the context (the this keyword) is the DOM element that triggered the event, not your CharCounter object instance.
You could do something like this:
function CharCounter(sourceId, statusId) {
this.sourceId = sourceId;
this.statusId = statusId;
this.count = 0;
}
CharCounter.prototype.updateAll = function() {
var text = document.getElementById(this.sourceId).value;
document.getElementById(this.statusId).innerHTML = text.length;
};
CharCounter.prototype.start = function() {
// event binding
var instance = this; // store the current context
document.getElementById(this.sourceId).onkeyup = function () {
instance.updateAll(); // use 'instance' because in event handlers
// the 'this' keyword refers to the DOM element.
};
}
window.onload = function () {
var myCharCounter = new CharCounter('textarea1', 'status');
myCharCounter.start();
};
Check the above example running here.
The expression "myCounter.updateAll" merely returns a reference to the function object bound to "updateAll". There's nothing special about that reference - specifically, nothing "remembers" that the reference came from a property of your "myCounter" object.
You can write a function that takes a function as an argument and returns a new function that's built specifically to run your function with a specific object as the "this" pointer. Lots of libraries have a routine like this; see for example the "functional.js" library and its "bind" function. Here's a real simple version:
function bind(funcToCall, desiredThisValue) {
return function() { funcToCall.apply(desiredThisValue); };
}
Now you can write:
document.getElementById('myTextField').onkeydown = bind(myCounter.updateAll, myCounter);
You can:
function start() {
//This is the problem
document.getElementbyId('mytextfield').onkeydown = function() { myCounter.updateAll(); };
document.getElementbyId('mytextfield').onkeyup = function() { myCounter.updateAll(); };
}
In ASP.Net Ajax you can use
Function.createDelegate(myObject, myFunction);
I want to do something like this but simpler.
The idea is to have the user click on bolded text and have a text field appear where they can change all the values of a role-playing character. Then when the value is changed, have the text field disappear again replaced by the updated bolded text value.
I can do this already using an annoying text box alert. But I would rather have something similar to this below to replace all that.
I have searched for months and CMS is the closest to answering my question in the simplest way with a full html example. Nobody else on the net could.
So my question is, how do I do this?
I have multiple objects(characters) and need this.elementId to make this work.
I've modified this example but it breaks if I try to add to it.
html>
head>
title>Sandbox
/head>
body>
input id="textarea1" size=10 type=text>
script>
function CharCounter(sourceId, statusId)
{this.sourceId=sourceId;
this.statusId=statusId;
this.count=0;
}
CharCounter.prototype.updateAll=function()
{text=document.getElementById(this.sourceId).value
document.getElementById(this.statusId).innerHTML=text
}
CharCounter.prototype.start=function()
{instance=this
document.getElementById(this.sourceId).onkeyup=function ()
{instance.updateAll()}
}
window.onload=function ()
{myCharCounter=new CharCounter('textarea1', 'status')
myCharCounter.start()
}
/script>
/body>
/html>