AngularJs pass model value + model name to function in controller - javascript

$scope.populateMap=[{name: "ABC", code: "123"}, {name: "XYZ", code: "345"}]
//Want to send model name + value of model Currently sending ngObject.MainObj.specificFormatObj
HTML
<select ng-model="ngObject.MainObj.specificFormatObj" ng-change="ngObject.MainObj.specificFormatObj">
<option></option>
<option ng-repeat="i in populateMap" value="{{i}}">{{i.name}}</option>
JS
// CONTROLLER CODE JSON parse object to get name and code GOT parsedObj
$scope.genericSetLookups=function (Obj) { // want to do something like get the ngmodel string + the value, currently only value comes in
Obj.code=parsedObj.code;
Obj.name=parsedObj.name
};
More Explanation: ngObject.MainObj.specificFormatObj
I want in my model to store value of lookups in a specific way, with name and code. On the UI I populate using ng-repeat , So when I select a particular value I can either take i.name as display and set value as i.code .
But if i do that my ngObject.MainObj.specificFormatObj.name will be null and the value will get set to ngObject.MainObj.specificFormatObj.code by using ng-model ,so that is the reason in value I am taking i, not i.code or i.value ,now in the map i have code and name pair.
I sent it to a function and parse it, and set the value to ngObject.MainObj.specificFormatObj.code=inputTofunc.code respectively for name. In this case in the ng-change i pass on the ngObject.MainObj.specificFormatObj.code ,rather i want to set i from the map to ngObject.MainObj.specificFormatObj send it to function also the model string which in this case would be "ngObject.MainObj.specificFormatObj" .
So for 10 lookups i can write a generic code ,where the model name and model value i can send as parameter to function and set it there, the above way am doing is probably hardcoding values which i want to set to model in a specific format.

Since you need to pass the model name as a parameter, pass it as a string like this from html :
ng-change="genericSetLookups('ngObject.SomeObject.abc',ngObject.SomeObject.abc)"
And in the controller as the model name contains "." we cannot use the name directly as the key. We need to parse the model name. I have cooked something up after searching a bit. Hope it works.
Controller code:
$scope.genericSetLookups(modelName, value){
Object.setValueByString($scope, modelName, value);
}
Object.setValueByString = function(o, s, val) {
s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
s = s.replace(/^\./, ''); // strip a leading dot
var a = s.split('.');
for (var i = 0, n = a.length; i < n; ++i) {
var k = a[i];
if (k in o) {
if(i != n-1){
o = o[k];
}
else{
o[k] = val;
}
} else {
return;
}
}
return o;
}
Credit must also go to #Alnitak for the answer here

I didn't really understand your problem and the comments didn't make it clearer for me. What I tried to do is give you an example of how I would handle a select box and the model.
I would loop over the options with ng-options and show the selected option by putting {{selected.name}} in the template. Ofcourse if you would want to format the selected value in anyway or react to a change you can use ng-change.
Hope it helps.
Here is my JSFiddle

I'm not sure if I understood your question. If you want to save in your model the value code + name, maybe this code can help you:
<select ng-model="ngObject.MainObj.specificFormatObj" ng-options="(ppm.code + '-' + ppm.name) as ppm.name for ppm in populateMap">
</select>
jsfiddle

Related

I need to take max value from different id of database from $scope to others

So I have this database:
I need to sort those child id(s) (from type1 to type10), show sorted value at UI and the biggest value of id will be the new variable that I want to put that $id (example in this case the biggest value is 84.5 which has an $id named type2) to be sifat="type2".
Should I declare them in a new variable and then sort it?
You'll have to do sorting on the client, but you can use angularfires $firebaseArray to get everything into an array at least:
$firebaseArray(...child('result')).$loaded().then(function(types){
$scope.types = types;
})
And then sort in the dom (or wherever else you'll need too)
<div ng-repeat="type in types | orderBy:'value'"></div>
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebasearray
I solved this
fireBaseData.refUser().child($scope.user_info.uid).child("result")
.orderByValue()
.limitToLast(1)
.on("value", function(snapshot){
snapshot.forEach(function(data){
console.log("The "+ data.key()+" score is "+ data.val());
$scope.highestval = data.val();
$scope.highesttype = data.key();
fireBaseData.refUser().child($scope.user_info.uid).update({ // set
sifat: $scope.highesttype
});
});
}
and also the filter function from #Mathew Berg is working as well, thanks

ng-repeats, showing record while it's value is a part of field of another object

I've got objects 'ing' with a field named 'id' and another one called 'fObj' with a field named 'contain'.
By using ng-repeat i'd like to show only these 'ing' objects where ing.id is a part of fObj.contain
e.g.
ing=[{id: 1,field: value},{id:2, field: othervalue},{id:3, field: cat}];
fObj={field1: value1, field: value2, contain: ':1:3:'};
By having this contain value I'd like to show only ing's with id=1 and id=3
Yeah, I know there are two types of data (number and string) but even if i changed numbers to strings it still didn't work
I just dont't know how to make it works. It's probably some kind of custom filter, but I've tried couples and nothing happend.
I would be glad if you suggest me a solution.
Thanks
In your controller,
var ids = fObj.contain.split(':');
// the array for your ng-repeat
var displayIng = [];
// loop the objects, see if the id exists in the list of id's
// retrieved from the split
for(i = 0; i < ing.length; i++) {
if(ids.indexOf(ing.id.toString()) displayIng.push(ing[i]);
}
I would split the numbers out of fObj.contain; and use them as hashmap object keys for simple filtering of the array
var ing=[{id: 1},{id:2},{id:3}];
var fObj={contain: ':1:3:'};
var IDs = fObj.contain.split(':').reduce(function(a,c){
a[c]=true;
return a;
},{});
// produces {1:true,3:true}
var filtered = ing.filter(function(item){
return IDs[item.id];
});
console.log(filtered)

JS and ExpressionEngine - Remove KV pairs by duplicate values only?

We're building a site with ExpressionEngine. We are running a SQL query to gather up all member IDs for a specific member group. After that, we are using EE tags to get data from a custom member field for each member ID.
The ID and field data need to stay paired, as we will be populating a drop-down so that the ID is the value and the field data is the text, so we are currently putting them into a JS array as key/value pairs. The call is as follows:
var array= [
{exp:query sql="SELECT * FROM exp_members WHERE group_id = 5"}
{exp:member:custom_profile_data
member_id="{member_id}"}
{if company != ''}
{{member_id}:"{company}"},
{/if}
{/exp:member:custom_profile_data}
{/exp:query}
};
This gives us the output:
var array = [
{1:"name01"},
{2:"name02"},
{3:"name01"},
{4:"name03"}
];
Now, our problem. We need to remove objects based on duplicate field data (values) only, so the above array would look like this:
var array = [
{1:"name01"},
{2:"name02"},
{4:"name03"}
];
None of these IDs (keys) will ever be the same, but the field data (values) can be. So we want to keep the first KV pair that comes through with a unique value, but remove any subsequent dupes of that value - despite the fact that they will not be true "duplicate values" due to a different ID (key).
Keeping in mind that the KV pairs are all dynamic, is there any possible way to do this via JS so we can create a new array for the cleaned data to pass to the drop-down?
You could handle the duplications by modifying your MySQL query. (In my example, my custom field ID was 1.)
var myArray = [];
{exp:query sql="SELECT MIN(m.member_id) AS co_member_id, d.m_field_id_1 AS company FROM exp_members m INNER JOIN exp_member_data d ON m.member_id = d.member_id WHERE d.m_field_id_1 != '' AND m.group_id > 0 GROUP BY d.m_field_id_1;"}
myArray.push({{co_member_id}: "{company}"});
{/exp:query}
This query would use the first (in the ordinal sense) member_id found; you could also change the MIN to MAX and get the last.
This will give you a clean output in your source, without the need for any additional JS processing. I'd also recommend changing the names of the variables you're outputting as to not conflict in EE's parsing.
I would do it like...
function removeDups(arry){
var tmp = {}, retainIdx=[], newArry=[];
arry.forEach(function(obj, idx){
var val = obj[Object.keys(obj)[0]];
if(val && !tmp[val]){
retainIdx.push(idx);
tmp[val] = true;
}
});
retainIdx.forEach(function(i){
newArry.push(arry[i]);
});
return newArry;
};

How to replace ' / ' with '-' inside ObservableArray ? Knockout js

Well i am trying to pass an observable array via ajax call to my controller but i get every value there except date . i get something like '01-01-01' etc .
I found the issue but unable to fix that as i dont know how to replace / with - .
My ObservableArray have around 10 list items each list item holds a many properties out of those startDate holds the date like ("23/10/2014") . i just need something like ("23-10-2014") .
Tought of posting my function's and more i hope thats not required in this case i believe .
Let me explain with bit of code and sample data :
function myarray()
{
var self=this;
self.startDate=ko.observable("");
self.name=ko.observable("");
self.place=ko.observable("");
}
MyObservableArray :
self.Main= ko.observableArray();
In between i do some stuff to load Data into self.Main and i am sending self.Main to controller having data like below :
self.Main[0] holds :
startDate() -->gives you "23/10/2014" //individual observables inside onservable array
name() --> "jhon"
place()--> "croatia"
Likely
self.Main[9] holds :
startDate() --> "29/05/2012"
name() --> "pop"
place()--> "usa"
I am trying like i want to alter the self.Main() and replace the startDate and use the same self.Main to send to my controller . Once after replacing in self.Main when i check date the / should be replaced with - .
Possible solution : i can use a different observable array and push all the VM's of Main into it but i am trying to do on self.Main without using other .
If someone can show some light it is much appreciated .
What I got that you are facing problem in escaping / in replace.
Try this
"(23/10/2014)".replace(/\//g,"-") //returns "(23-10-2014)"
I tried something for you using simple JS
var arr = [{date:"(23/10/2014)"},{date:"(23/10/2014)"},{date:"(23/10/2014)"},{date:"(23/10/2014)"}];
arr.forEach(function(obj){obj.date = obj.date.replace(/\//g,"-")});
console.log(arr) //will print date field as "(23-10-2014)" for all objects.
One solution would be to add a computed value that returns the array with the right values.
self.Main = ko.observableArray([...values here...]);
self.MainComputed = ko.computed(function() {
var computedArray = [];
self.Main().forEach(function(item) {
var newItem = myarray(); //Create a new item.
newItem.name(item.name());
newItem.place(item.place());
newItem.startDate(item.startDate().replace(/\//g,"-"));
computedArray.push(newItem);
});
return computedArray;
});
Then use the computed value in the places where you need the values with -.
I can think of two other ways to solve your issue, when taken into account that you want to use self.Main:
Replace the / with - before setting startDate on your item.
Change startDate to a computed value while storing the original value in another variable.
The first solution should be pretty straight forward (provided that it is a valid solution).
The second solution would look something like this:
function myarray()
{
var self=this;
self.originalStartDate = ko.observable("");
self.name = ko.observable("");
self.place = ko.observable("");
self.startDate = ko.computed(function() {
if(self.originalStartDate()) {
//We can only replace if the value is set.
return self.originalStartDate().replace(/\//g,"-");
}
else {
//If replace was not possible, we return the value as is.
return self.originalStartDate();
}
});
}
Now when you set the values you do something like:
var item = myarray();
item.originalStartDate = "01/01/2014";
Then when you get the value of startDate you would get "01-01-2014".
I haven't used Knockout.js but you can do this with a Javascript replace:
var str = [your array value] ;
var res = str.replace("/", "-");
For more information:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace

Model Bind to a List<> when Posting JavaScript Data Object

I'm trying to post a JavaScript data object with the following:
$.post(frm.attr("action"), data, function(res)
{
// do some stuff
}, "json");
where 'data' takes the structure of
data
- panelId
- siteId
- ConfiguredFactsheetId // this is an array of CheckBox ids that correspond to ConfiguredFactsheets
- 123
- 234
- 345
With this, both site & panel are correctly instantiated & bound with their data but the List object is null.
public JsonResult Edit(Site site, Panel panel, List<ConfiguredFactsheet> configuredFactsheets)
{
// do stuff
return Json(success);
}
Now, I realise that my 'data' object's ConfiguredFactsheetId property is just an array of id values. Do I need to specify that each value corresponds to a configuredFactsheetId property of my ConfiguredFactsheet object? If so, my data object would take a form similart to
data
- panelId
- siteId
- ConfiguredFactsheet // this is an array of CheckBox ids that correspond to ConfiguredFactsheets
- ConfiguredFactsheetId:123
- ConfiguredFactsheetId:234
- ConfiguredFactsheetId:345
but this obviously won't work because every time I add a new ConfiguredFactsheetId to the object, it'll just overwrite the previous one.
I know I can do this if I built a query string of the form
"&ConfiguredFactsheet[i].configuredFactsheetId = " + configuredFactsheetId;
but I'd like to contain everything in a single data object
Any suggestions? Do I need to explain anything (probably everything!) more clearly?
Thanks
Dave
In the end, this worked:
var valuesArray = objCheckBoxes.map(function()
{
return $.getAttributes($(this));
});
var obj = new Array();
$.each(valuesArray, function(item) { obj.push($(this)[0]); });
$.each(obj, function(i)
{
// basically I take the rule where you need to append
// the index to the type, and I apply it here.
data["configuredFactsheets[" + i + "].configuredFactsheetId"] = $(this).attr("configuredFactsheetId");
});
Note: read about $.getAttributes
An alternative is to post:
?myValues=1&myValues=2&myValues=3
And accept it as an IEnumerable
public ActionResult DoSomething(IEnumerable<int> myValues) {
...

Categories

Resources