How to change the method within a class dynamically? - javascript

I want to change the method changeThis dynamically by replacing the method with the value of an radio element. So if I select event1, the method needs to be changed to Class.event1()
<input
type="radio"
class="radio-input"
id="1"
value="event1"
ng-model="$ctrl.eventType"
ng-change="$ctrl.updateEvent()" />
JS:
updateEvent() {
const getEvent = Class.changeThis({
title: 'Happy Time',
location: 'New York, NY',
description: 'Let\'s go!'
});
}
I tried:
const getEvent = Class + '.'+ this.eventType({
title: 'Happy Time',
location: 'New York, NY',
description: 'Let\'s go!'
});
}
but get the error eventType is not a function. When I change it to a function it still doesn't work.

You can access objects property (or method) dynamically like this:
myObj["my" + "property"]
So, in your case it would be:
Class[this.eventType]({ ... });

Related

How to store radio button value as variable

I tried to make a multilanguage site with html and javascript.
For selecting the language I created three radio boxes (values: en, de, fr).
The words which should be displayed are stored in a javascript object.
Here is the code:
$('#lang-setting').on('change', function () {
var lang = $('input:checked', '#lang-setting').val();
console.log(lang);
alert(lang);
$('#latitude-n').html(lang.latitude);
$('#longitude-n').html(lang.longitude);
$('#accuracy-n').html(lang.accuracy);
$('#words-n').html(lang.words);
$('#map-n').html(lang.map);
$('#test').html(de.test);
});
alert(lang) and console.log give the right language every time I select a language.
But: the other words don't change. They do if I replace the 'lang' with f.e. 'de' (see last code line).
Your variable named lang is a string because you're setting it to the value of the radio input, so lang.latitude, lang.longitude, lang.accuracy, lang.words, and lang.map are all undefined.
I'm assuming you have global variables such as de set since you said de.test works.
It would probably be easiest to put all of those languages into a single object that you can then reference by the key, or the value of the radio input. I've also added a variable that allows you to select the default language and the function that will be performing the actual html change.
var translate = {
default: 'en',
en: {
latitude: 'latitude',
longitude: 'longitude',
accuracy: 'accuracy',
words: 'words',
map: 'map',
},
de: {
latitude: '',
longitude: '',
accuracy: '',
words: '',
map: '',
},
fr: {
latitude: '',
longitude: '',
accuracy: '',
words: '',
map: '',
},
changeText: function(lang) {
$('#latitude-n').html(translate[lang].latitude);
$('#longitude-n').html(translate[lang].longitude);
$('#accuracy-n').html(translate[lang].accuracy);
$('#words-n').html(translate[lang].words);
$('#map-n').html(translate[lang].map);
}
}
Since you didn't post the HTML of your three radio buttons, I'm going to instead give them name attributes instead of id's of with the value "lang-settings" because having duplicate id's is invalid HTML. Below is the minimal HTML for these radio buttons.
<input name="lang-setting" value="en" type="radio" />
<input name="lang-setting" value="de" type="radio" />
<input name="lang-setting" value="fr" type="radio" />
Then for your listener, I've switched it to listen for "clicks" instead of changing, because the values of the radio button isn't actually changing, they're staying as "en", "de", and "fr". I've also added the function call in document ready to run your default language selection on page load.
$('input[name="lang-setting"]').on('click', function(e){
var lang = $(this).val();
translate.changeText(lang);
});
$(document).ready(function(){
translate.changeText(translate.default);
});
Here's a working demo of it on JSFiddle
It doesn't work that way, you need brackets notation.
var words = {
de: {
lat: "Breitengrad",
lon: "Längengrad"
},
en: {
lat: "Latitude",
lon: "Longitude"
},
fr: {}
};
function changeLanguage() {
var lang = $('#lang-setting input:checked').val();
$('#latitude-n').html(words[lang].lat);
}
$('#lang-setting input').click(changeLanguage);
changeLanguage();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="lang-setting">
<input type="radio" value="en" name="lang" checked>En</option>
<input type="radio" value="de" name="lang">De</option>
<input type="radio" value="fr" name="lang">Fr</option>
</div>
<p>
<span id="latitude-n"></span>: <input />
</p>

Is there any easy way to convert multipart/form data to an array in NodeJS?

I am trying some input to get post data as array in Sails/nodeJS;
When I try with this way then get data as array perfectly.
<input type="text" class="form-control" name="answer[1][txt]">
<input type="text" class="form-control" name="answer[1][img]">
<input type="text" class="form-control" name="answer[2][txt]">
<input type="text" class="form-control" name="answer[2][img]">
Output:
answer:[ { txt: 'ans 1', img: 'yes' }, { txt: 'ans 2', img: 'yes' } ]
But when I use enctype(enctype="multipart/form-data") attribute in form then can not get data as previous method.
Output:
'answer[0][txt]': 'ans 1', 'answer[0][img]': 'yes',
'answer[1][txt]': 'ans 2','answer[1][img]': 'yes',
I don't know what happened when I use enctype attribute. I want only first return output data with using enctype(multipart/form-data) attribute.
Thank You
You can create a new object from the currently returned object; use for..in loop to iterate object, match "txt" or "img" portion of property, set value to value of existing object
let data = {
'answer[0][txt]': 'ans 1',
'answer[0][img]': 'yes',
'answer[1][txt]': 'ans 2',
'answer[1][img]': 'yes'
};
let res = {
answer: []
};
for (let prop in data) {
res.answer.push({
[prop.match(/txt|img/)[0]]: data[prop]
})
}
console.log(res);

AngularJS ng-click to go to view

Hi I have a button that I have a ng-click directive on that I just want to load a view. I've looked at some pages online, and I'm not able to figure out how to get the button to work. My button looks like this:
<button class="btn default-btn lookupbtn" ng-click="go('/lookup')">Lookup</button>
and my controller like this:
(function () {
'use strict';
angular.module('crm.ma').controller('LookUpCtrl', LookUpCtrl, function($location){
function LookUpCtrl() {
var vm = this;
vm.results = [
{
accountId: 1,
accountName: 'some name',
address: '201 some st',
city: 'Columbus',
state: 'OH',
zip: 'zip',
phone: '899-629-7645',
parentName: 'Parent 1',
accountType: 'Type 1',
accountStatus: 'Status 1',
creditTerm: 'Term 1'
},
{
accountId: 2,
accountName: 'house home',
address: '2963 this st',
city: 'Columbus',
state: 'OH',
zip: 'zip',
phone: '899-627-7592',
parentName: 'Parent 2',
accountType: 'Type 2',
accountStatus: 'Status 2',
creditTerm: 'Term 2'
}
];
vm.go = function (path) {
$location.path(path);
};
}
})
}());
I'm really new to Angular and I'm just not sure what I'm doing wrong. If any other code is needed please let me know. Thanks.
Instead of that you could convert that button to anchor & apply the CSS classes of button of bootstrap, that will give you look and fill of button it & then use ng-href attribute to have redirection URL on it inside SPA.
<a class="btn btn-md" ng-href="#/lookup">Lookup</a>
Additionally as #charlietfl suggested you need to add missing dependency of $location, $scope would also needs to add if you are following the second way.
Controller definition is incorrect. Should look like:
angular
.module('crm.ma')
// only 2 arguments, name and function
.controller('LookUpCtrl', LookUpCtrl);
// add the dependency injections to function
function LookUpCtrl($location) {
var vm = this;
vm.results = [... ];
vm.go = function (path) {
$location.path(path);
};
}
Then for go() you have no function go() in your controller and if you did you wouldn't use a leading / for $state.go()
Can use ui-sref to point to a state in html if using ui-router:
<a class="btn btn-md" ui-sref="lookup">Lookup</a>

knockout.js dependent variable selects

[ Please see updates at the bottom ]
I'm trying to make knockout depended selects, it's intended to make a "product" selection by these attributes, for example a product can have "size" and "material", if I selected "size", a knockout script make a request to the backend and retrieves which "material" available for the selected size, in other words, if an attribute is selected, other attributes are filtered out to show only available values ("all sizes": 1,2,3,4,5; "aluminium": 1,4).
Attributes list are completely dynamic, there are about 80 attributes which can be linked to the products in arbitrary way.
Are there any "best practices" for this situation?
I am trying to solve it with code like this, without success yet:
var ViewModel = function(data) {
var self = this;
self.data = data;
self.attributes = ko.observableArray();
self.data.forEach(function(item, i, a) {
// I passed .self to catch it later
// in products as view_model.attributes().
self.attributes.push(new VariableProduct(item, self));
})
};
var VariableProduct = function(item, view_model) {
var self = this;
self.attribute_name = ko.observable(item.name);
self.attribute_value = ko.observable('--');
// list of attribute values
self.attribute_values = ko.computed(function() {
var result = {};
view_model.attributes().forEach(function(attribute, i, a) {
// here I try to filter each attributes lists by values
// it doesn't work well
if (attribute.attribute_name() != self.attribute_name() && self.attribute_value() != '--') {
result = attribute.attribute_values().filter(
function(value) {
return value.indexOf(self.attribute_value()) >= 0;
});
}
});
return result;
});
};
UPDATE 1:
With Dnyanesh's reference to ko.subscribe(), i've achived these results, isn't ok yet, but a progress:
http://jsfiddle.net/xwild/65eq14p3/
UPDATE 2:
At the end it was solved with knockout.reactor and knockout.mapping plugins.
Related stackoverflow question with details and the answer.
For dependent select I think you can use subscribe in following manner
var vm = {
sizes: ko.observableArray([
{ name: 'size 1', id: 1},
{ name: 'size 2', id: 2},
{ name: 'size 3', id: 3},
{ name: 'size 4', id: 4}
]),
selectedSize : ko.observable(0),
};
vm.selectedSize.subscribe(function(newValue){
alert('Selected Size is ---> ' + newValue )
// Here at this point call your ajax or backend method and bind the values which are coming form
});
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min.js"></script>
<select data-bind="
options: sizes,
optionsText: 'name',
optionsValue: 'id',
value: selectedSize,
optionsCaption: 'Choose Size...'"">
</select>
<select data-bind="
options: material,
optionsText: 'name',
optionsValue: 'id',
value: selectedMaterial,
optionsCaption: 'Choose Material...'"">
</select>
I know I am talking about only part of solution to your problem but, I think you need to divide your data object to bind it to various controls.

knockout object value changes but ui remains the same

I have a drop down list that is bound to a SelectedFormat value. The lists options are populated from external source on load and matches the view models data.Format object base on id.
Take a look at the js fiddle
Can anyone tell me why the model updates but the UI is not updating with the correct Format.Name
Thanks.
HTML:
<div data-bind="text:data.Format.Name"></div>
<select data-bind="
options:Controls,
optionsText: 'Name',
value: data.SelectedFormat"></select>
Model:
var jsonData = {
Id: "abc-123",
Name: "Chicken Cheese",
Format: {
Id: 2,
Name: 'Medium',
Other: 'Bar'
}
};
var self = this;
self = ko.mapping.fromJS(data);
self.SelectedFormat = ko.observable(
//return the first match based on id
$.grep(vm.Controls,function(item){
return item.Id === self.Format.Id();
})[0]
);
//when changed update the actual object that will be sent back to server
self.SelectedFormat.subscribe(function (d) {
this.Format = d;
},self);
In your code, you have Format and SelectedFormat. The former isn't an observable and so can't trigger updates. You have to use SelectedFormat instead.
<div data-bind="text:data.SelectedFormat().Name"></div>
Example: http://jsfiddle.net/QrvJN/9/

Categories

Resources