having problems returning value from functions - javascript

Hello Im having problems returning a value from the AmountToDisplay() function I feel like a module approach would be appropriate but since I'm new to OOP I've been having problems setting that up
function AmountToDisplay(){
$emitter = $({});
$('#amountItems').change(function(){
var amountchosen = $("#amountItems option:selected").val();
$emitter.trigger('amountUpdate', amountchosen);
});
$emitter.on('amountUpdate', function(e, val){
if(val == 2){
return 2;
}else if(val == 3){
return 3;
}else if(val == 4){
return 4;
}
})
}
I want to be able to do something like
if(AmountToDisplay() ==2){
..append 2 items to body
}else if(AmountToDisplay() ==3){
..append 3 items to body
}
console.log(AmountToDisplay()) gives undefined
instead of returning and I use the alert method alert(2), it works. I'm trying to get the values out of the select box so I could decouple separate the value from the event so I could use the value in other part of my code other parts in my code in this jsfiddle. Thanks in advance for your help.
EDIT THE thing is I want to be able to use the amount somewhere out of the change event. so if the user clicked 3 I want to be able to have that value so I could perform another function not related to the change event even though the value changes when the user inputs. pub/sub?

Try going through the backdoor. use arguments to cheat in the variable you want.
$emitter.on('amountUpdate', function(e, val){
console.log(arguments);
if(val == 2){
return 2;
}else if(val == 3){
return 3;
}else if(val == 4){
return 4;
}
})
you can see the variable you want is in arguments[1]
Also returning anything here doesn't serve a function. it does literally nothing.
You would need to pass it to an event handler.
so by modifying your code like this:
$emitter.on('amountUpdate', function(e, val){
val = arguments[1];
if(val == 2){
myEventHandlerfor2(val,e);
}else if(val == 3){
myEventHandlerfor3(val,e);
}else if(val == 4){
myEventHandlerfor4(val,e);
}
})
edit for showing how to put it in an object
function FruitBasket() {
this.apples = 0;
this.pears = 0;
this.bananas = 0;
this.iwonteatthat = 0;
}
FruitBasket.prototype.addFruit = function(which) {
switch(which) {
case 0 : this.apples++;break;
case 1 : this.pears++;break;
case 2 : this.bananas++;break;
case 0 : this.iwonteathat++;break;
}
}
FruitBasket.prototype.registerManipulator = function(manipulator) {
if(!(manipulator instanceof jQuery)) {
manipulator = $(manipulator);
}
manipulator.on('amountUpdate', jQuery.proxy(function(e, val){
val = arguments[1];
this.addFruit(val);
},this);
}
myFruitBasket = new FruitBasket();
myFruitBasket.registerManipulator($('#formfieldstuff'));
myFruitBasket.registerManipulator(document.getElementById('OtherManipulator'));

The return that do you have only exits the function of the event, but not the function AmountToDisplay.
The event must be outside the function
The function only need to return the value of the select with amountItems
The console.log or your logic must be inside the event
http://jsfiddle.net/mdf083Lb/2/
function AmountToDisplay(){
return $("#amountItems option:selected").val();
}
$("select").change(function(){
console.log(AmountToDisplay());
});

You don't need to defina an event method or something else, you can get selected value of select box where ever you want by using jquery selector :
var amountToDisplay = $("#amountItems option:selected").val();

Related

Javascript Click Event Pushing Multiple Duplicates to Array

In recreating the Simon game, I am trying to push a click event to an array and then immediately test that Array in a nested function. On the first pass it seems to work.
However, on the third run the array does not seem to clear.
The screen shot below also shows that each input is printed multiple times to the console.
Full code pen here - https://codepen.io/jhc1982/pen/NwQZRw?editors=1010
Quick example:
function userMoves() {
var userInput = [];
document.getElementById("red").addEventListener("click", function(){
userInput.push("red");
testington();
});
$(".red").mousedown(function(event){
redAudio.play();
$(".red").css("background-color", "red");
});
$(".red").mouseup(function(){
$(".red").css("background-color", "#990000");
});
function testington(){
if (userInput.length == pattern.length) {
for (var i = 0; i < userInput.length; i++) {
if (userInput[i] !== pattern[i]) {
alert("Game Over");
} else if (i === userInput.length -1 && userInput[i] === pattern[i]) {
userInput = emptyArr;
simonMoves();
console.log("user input is ",userInput);
} else {
continue;
}
}
}
}
}
I am sure it is something really obvious but have been stuck for hours.
I think the problem may be that you are assigning the click events every time the userMoves execute. That means every time the function is called the event is added to the elements, so after two calls to userMoves() when you click on red the event is executed twice, after three calls it is executed three times, etc.
The code that adds the event listener should be out of the userMoves function. The testington function should also be out of userMoves, which would get much simpler:
function userMoves() {
$("#score-text").text(level);
userInput = [];
}
Here's a Pen with working code: https://codepen.io/anon/pen/ppzqyY
You need to add the break; keyword to after alert("Game over");
function testington(){
if (userInput.length == pattern.length) {
for (var i = 0; i < userInput.length; i++) {
if (userInput[i] !== pattern[i]) {
alert("Game Over");
break; // Break the loop
} else if (i === userInput.length -1 && userInput[i] === pattern[i]) {
userInput = emptyArr;
simonMoves();
console.log("user input is ",userInput);
} else {
continue;
}
}
}
}

Knockoutjs subscribe event , ko.computed execution timing issue

I want to set different value to self.selectedTitleId() in knockoutjs when self.selectedQueryId changes, so i have added a subscribe to selectedQueryId.
I have another computed variable self.text which format the self.selectedTitleId with other variables.
My problem is , when i change the selectedQueryId value from UI, computed function gets called first, followed by subscribe call. Because of this, the text that i am trying to display always holds the previous selection value.
I want to hold the self.text computed function execution until selectedTitleId.subscribe function is completed so that self.selectedTitleId has current value.
Can someone help me? Thanks for your time!
Below is the html component which is used to bing selectedTitleId value with UI. backend js always shows the 'backendName' as value, even though i tried to set a different value using self.selectedTitleId("newValue").
html:
var sformat = (function() {
var pattern = /\{\{|\}\}|\{(\d+)\}/g;
return function () {
var parameters = arguments;
if(parameters[0]) {
console.log(parameters[0])
return parameters[0].replace(pattern, function (match, group) {
var value;
if (match === "{{")
return "{";
if (match === "}}")
return "}";
value = parameters[parseInt(group, 10) + 1];
return value ? value.toString() : "";
});
}
};
});
function test() {
return sformat.apply(this, arguments);
}
self.selectedTitleId = ko.observable('');
self.text = ko.computed(function () {
console.log("inside text function")
if (self.selectedTitleId && self.selectedQueryId()) {
console.log(self.selectedTitleId)
self.displayField = test(self.selectedTitleId, self.selectedQueryId(),self.queryValue());
}else if(self.selectedTitleId && self.selectedQueryId() && self.queryGreaterValue() && self.queryLesserValue()){
self.displayField = test(self.selectedTitleId, self.selectedQueryId(),self.queryValue(),self.queryGreaterValue(),self.queryLesserValue());
}
return self.displayField;
});
self.selectedQueryId.subscribe(function (newValue) {
$.getJSON("json/queries.json", function (allData) {
var mappedData = $.map(allData, function (item) {
if(item.DisplayName == "Price"){
if(newValue == "range") {
self.selectedTitleId(item.RangeBackEndFieldName);
console.log("range");
console.log(item.RangeBackEndFieldName); //Prints new string
console.log(self.selectedTitleId()); //Print old value-
}else if(newValue == "$gt:" || newValue == "$lt:"){
self.selectedTitleId(item.BackendFieldName);
});
}
}
});
});
});
Unless there is something else you are not telling us, it doesn't make sense for selectedTitleId to be a ko.computed. Just use a regular observable:
self.selectedTitleId = ko.observable();
self.selectedQueryId.subscribe(function (newValue) {
$.getJSON("json/queries.json", function (allData) {
var mappedData = $.map(allData, function (item) {
if(item.DisplayName == "Price"){
if(newValue == "range") {
self.selectedTitleId(item.RangeBackEndFieldName);
});
}else if(newValue == "$gt:" || newValue == "$lt:"){
self.selectedTitleId(item.BackendFieldName);
});
}
}
});
});
});
Now when selectedTitleId is changed in your callback, it should trigger text to re-evaluate.
The problem with your original wasn't that it was updating text first, it was that it wasn't re-evaluating when you changed selectedTitleId. See here:
if (self.selectedTitleId() && self.selectedQueryId()) {
This means your computed property is dependent on both selectedTitleId and selectedQueryId, updating either will cause the function to run again. But in your original code, you completely replaced self.selectedTitleId with an entirely new function, but your computed is still dependent on the old one (which is unchanged).

Javascript .click() different for elements w/ same class

I'm pretty new to Javascript/Jquery and am implementing a real simple image carousel for practice and ran into a problem regarding Jquery's "click" method.
The code I currently have is as follows:
$(document.getElementsByClassName("traverse")).click(function() {
if(this.id = "left"){
if (current == 0) {
current = images.length-1;
}
else {
current -= 1;
}
}
else if(this.id = "right") {
if(current = images.length-1) {
current = 0;
}
else {
current += 1;
}
}
$(document.getElementById("image-view")).css("background-image", "url(" + images[current] + ")");
});
With this code there are no errors, but every time I click either the "#right" or "#left" button, they both run code as if "this.id = 'left'". While I understand I can simply separate the two and this will work fine, is there a way I can do it similar to what I have now where I'm applying this event to the class, but differentiating the behavior by the id?
Thanks!
Typo
== to compare
= to assign
Strict equal (===) Returns true if the operands are equal and of the
same type
if(this.id === "left"){
^
and better use
class selector
$('.traverse').click(function(){ .. });
Problem with your code
you are assign this.id = "left" every time in if condition so is condition is always true
if(this.id = "left"){
You're setting this.id to left by only using a single = sign. Try this:
$(document.getElementsByClassName("traverse")).click(function(event) {
if(event.target.id === "left"){
and so on.

Exit from a javascript function

I saw many places similar question but couldn't fix it.
Here's my function:
function validate_form(){
$('#form_data input[type="text"]').each(function(){
value = $(this).val().trim();
if(value != '' && value != null && value != 0 ){
return true;
}
});
return false;
}
Its not exiting on return true;. I have also tried e.preventDefault() but no use.
return will return from the function it is in. In your code, that is the anonymous function you pass to each. See the documentation for each:
You can stop the loop from within the callback function by returning false.
You are returning true, not false so you aren't stopping the loop. Change true to false on line 5 of the function.
function validate_form(){
$texts=$('#form_data input[type="text"]'); //cache the object
var len = $texts.length;
var validItems=0;
$texts.each(function(){
value = $(this).val().trim();
if(value === ''){ // value of a text input cannot be null
// or zero unless you've changed in with JS
return false;
}
validItems++;
});
return len===validItems;
}
The function doesn't exactly show what item is invalid, just returns false if any of the items is invalid.
You have to let the .each() finish before you return from the main function body. You can keep a counter of valid entries you have come across and let the return value depend on that:
function validate_form()
{
var items = $('#form_data input[type="text"]'),
count = items.length,
valid = 0;
items.each(function() {
value = $(this).val().trim();
if (value != '' && value != null && value != 0 ) {
++valid;
}
});
return valid !== count;
}
Btw, I've changed the return value to false if there's at least one invalid entry; assuming you're using this as onsubmit="return validate_form()".

call another functions when first function return true, within one onclientclick

I want to call two functions and if the first returns true then continue to the second, and if it returns false then show an error. This would be defined in one onclientclick.
If only one function is to be called after I clicked the button, the function works.
However, if I combine and write it like this:
TestCheckBox() and TestCheckBox2() are same function, I just need it to validate two gridviews
<script type="text/javascript">
var TargetBaseControl = null;
window.onload = function () {
try {
//get target base control.
TargetBaseControl =
document.getElementById('<%= this.GridView1.ClientID %>');
}
catch (err) {
TargetBaseControl = null;
}
}
function TestCheckBox() {
if (TargetBaseControl == null) return false;
//get target child control.
var TargetChildControl = "chkRow";
//get all the control of the type INPUT in the base control.
var Inputs = TargetBaseControl.getElementsByTagName("input");
for (var n = 0; n < Inputs.length; ++n)
if (Inputs[n].type == 'checkbox' &&
Inputs[n].id.indexOf(TargetChildControl, 0) >= 0 &&
Inputs[n].checked)
return true;
alert('Select at least one checkbox!');
return false;
}
</script>
The problem is when TestCheckBox() returns true, TestCheckBox2() does not work, in this case it does not validate the checkboxes.
How do I make it work perfectly?
Try this:
<asp:.... OnClientClick = "return (TestCheckBox() && TestCheckBox2());" ...

Categories

Resources