ionic 3 input data binding is updating the different arrays of same type - ionic-framework

I have a problem in input data-binding for one of our ionic 3 application. Whenever input changes which is changing the array values of different arrays of same type.
Here is my HTML
<ion-list>
<ion-item-sliding *ngFor="let item of storageItem ; index as i">
<div class ="itemList">
<input type="number" [value] ="item.storageOrderQuantity" (blur)="updateInputItemValue(item)"
[(ngModel)]="item.storageOrderQuantity" />
</div>
</ion-item-sliding>
</ion-list>
When ever input value changes, it is updating 'storageItem' array along with other arrays which has the same object(there are some other arrays 'item').
Here is my arrays declaration. Item is a model class.
item: Item[];
storageItem: Item[] = [];
storageItem' is a subset of 'item
Can anybody tell what would be the mistake in data-biding?

You have mentioned that storageItem is a subset of item
You probably already know this, Arrays and Object use concept of assign-by-reference. If you don't know this then read below article on Medium.
https://medium.com/#naveenkarippai/learning-how-references-work-in-javascript-a066a4e15600
So if you have the same object in both the arrays then updating one array will update the another,
const obj = { name : 'value' };
const arr1 = [1,2,3,obj];
const arr2 = [4,5,6,obj];
obj.name = 'yash'; // both arrays will have updated object
Now if you want to avoid this, then you can create a copy of the object before using it in another array.
Take reference from https://flaviocopes.com/how-to-clone-javascript-object/
item: Item[] = [
{ id : 'item1', list : [] },
{ id : 'item2', list : [] },
{ id : 'storageItem', list : [...storageItem] }
];
storageItem: Item[] = [list of storage items];
Now storageItem and item > id='storageItem' point to different arrays.
So your template will only update the storageItem now.

Related

Repeat the columns using data-sly-repeat based on the number entered in the cq dialog. Columns are not repeating

I want to repeat the parsys in the columns based on the number of columns added in cq dialog. I can only get one column and the numbers of columns as entered
<div class="items">
<div data-sly-repeat="${grid.cols}" class="col col-lg-4 col-md-2 pt-2 pb-2">
<div data-sly-resource="${'content-{0}' # format=[colList.index], resourceType='wcm/foundation/components/parsys'}"></div>
</div>
</div>
</div>
carousel.js:
"use strict";
use(function() {
var properties = granite.properties,
colCount = properties.numberofcolumns ? properties.numberofcolumns : 3,
cols = '';
return {
"cols" : colCount
};
});
data-sly-repeat expects a list, not a number. You're only returning the number of columns. If you return an n-element list, data-sly-repeat will render an element for each item in the list.
It's a bit of a hack but in your carousel.js, you'd have to return an array with a list of values. The primary use case of data-sly-repeat (and data-sly-list) is to iterate over the elements of a collection returned by the underlying Java/JS code and output the properties of each item in the list. In your case, the only difference between the repeated div elements is the index.
use(function() {
var properties = granite.properties,
colCount = properties.numberofcolumns ? properties.numberofcolumns : 3;
var resultList = [];
for (var i = 0 ; i < colCount ; i++) {
resultList.push(i);
}
return {
"cols" : resultList // data-sly-repeat expects a collection
};
});
On a more general note, it seems what you're aiming to do is to include a bunch of paragraph systems by name to achieve some sort of column layout. Before attempting this, I would consider using the OOTB Layout Container component, which can be resized in Edit mode to fit any number of columns without any new development.

Equivalent of StructKeyList() for struct value

StructKeyList() will give me list of struct key with comma delimited. Now I need to get struct value with comma delimited. Right now this is what I'm doing to get value
<cfloop collection="#form#" item="key" >
#form[key]#,
</cfloop>
How can I get list of value from struct without loop? Thanks in advance.
I go through your problem. As per my knowledge is not possible to get list of value in structure within single functions. We have to loop the key and get the value of each. But I can give a solution for to get struct value with comma delimited.
<cfset strNew = {"a":"10","b":20,"c":30}>
Here strNew is my sample structure.
<cfset myList = ''>
<cfloop collection="#strNew#" item="key" >
<cfset myList = listappend(myList,structfind(strNew,key))>
</cfloop>
<cfdump var="#myList#" />
Here I've loop over the structure keys and find the value of an particular key and append that in to and list by using listappend and structfind functions.
So you no need to put like #structure[key]#,In your end of comma(,) is also added the last value of key too. For example your code should return 10,20,30,.
So you no need to do like that. use structfind and listappend you can avoid end of the comma also. Hope it's help you.
Since you're using CF2016, if you want to avoid a loop, you can always use one of the higher-order functions like reduce().
fields = formScope.reduce( function(result, key, value) {
result.append(value) ;
return result ;
}, [] ) ;
This takes the struct of your form scope (formscope) and uses reduce() to step through it and take it down to a single value (which is the struct values turned into an array). Then we make the returned array into a list.
writeDump( fields.toList() )
My full test code is at https://trycf.com/gist/f00cc62cd4631f44070faf8008e6788f/acf2016?theme=monokai
<cfscript>
formScope = {
empty1 : "" ,
fieldl : "text1" ,
field2 : "text2" ,
empty2 : "" ,
field3 : "text3" ,
field4 : "text4" ,
empty3 : ""
} ;
fields = formScope?.reduce( function(result, key, value) {
len(value) ? result.append(value) : "" ;
return result ;
}, [] ) ;
writeDump( fields?.toList() ?: "Form doesn't exist." ) ;
</cfscript>
Giving us: text2,text3,text4,text1.
formScope is my simulated version of the form fields that would be passed to this page. I use mostly the member function versions of StructReduce, ArrayAppend and ArrayToList. I also use the initialVal optional parameter to initialize the reduction's result value as an array. I check that the value has a length (I could also trim if needed) before I insert a row in the array, allowing me to remove empty elements from my final list. I also use the safe navigation operator (?.) to do some basic validation to make sure the elements exist (like if the form didn't pass or the reduction produced invalid results) and to make it more error-resistant.
NOTE: I believe that can be taken back to be compatible with CF11, when ArrayReduce was introduced.
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-s/structreduce.html
http://ryanguill.com/functional/higher-order-functions/2016/05/18/higher-order-functions.html
https://helpx.adobe.com/coldfusion/cfml-reference/coldfusion-functions/functions-a-b/arraytolist.html

How to get values from input in sap.ui.table.Table?

In sap.ui.table.Table I have input field in one column. It will get nearly 300 records of data from back-end and binded in other columns.
User manually enters in the input field. Further, when he clicks on submit button I have to take all values from all input as array. Please give suggestions.
You can do it using data binding of table, as invoking getRows() on Table control to access Input fields of each row would not help in this case;it only returns only currently visible rows and you have around 300 records to access.
Here is the solution:
Get all data from back-end in JSONModel.
Add one property say inputValue to each item in model's data by iterating over it.
Bind this model to table and use inputValue property in table's template to bind column containing Input fields.
As JSONModel supports two-way binding, all the values which user has entered in an Input fields are available in your model.
And, lastly iterate over model's data to get inputValue for each row.
Above steps in action:
Step 1 and 2:
setModelForTable: function() {
var oModel = sap.ui.model.json.JSONModel( < URLToLoadJSON > );
var length = oModel.getData().results.length;
for (var i = 0; i < length; i++) {
var path = "/results/" + i + "/inputValue";
oModel.setProperty(path, "");
}
}
Step 3:
Now, that you have model with inputValue property in all the items of data, set the model on table; which will show all the Input fields in columns empty initially and will update the corresponding model entry as user modifies it.
<t:Column>
<t:label>
<Text text="User Input" />
</t:label>
<t:template>
<Input value="{inputValue}" />
</t:template>
</t:Column>
Finally, get all entered values in array.
var length = oModel.getData().results.length;
var aInputvalues = []
for (var i = 0; i < length; i++) {
var path = "/results/" + i + "/inputValue";
aInputvalues.push(oModel.getProperty(path));
}
I had the case which is a bit similar and I did it in the following way. Will work if you really do not need records which are not changed.
have a variable to store [] of changed records
Attach change to input field
on change push changed record to a variable
var source = event.getSource();
source.getModel().getProperty(source.getBindingContext().getPath());
or the value of the input field.
event.getSource().getValue();
In case you have a record Id you can just push this ID and input value.
4. on submit iterate through an []

Select/Get html node from an element using D3

Let's say I have an html object called element that I create using bellow code:
var xmlString = "<div class="parent"><span class="child"></span></div>"
parser = new DOMParser()
var element = parser.parseFromString(xmlString, "text/xml");
// or simply using jquery
var string = "<div class="parent"><span class="child"></span></div>"
var element = $(string);
What I want to do is to select span.child from element using D3, not from the document. Using d3.select('span.child') will try to look for the <span class="child"></span> in the html document.
I checked the documentation and it says:
A selection is an array of elements pulled from the current document.
But I want to select not from the document but from the above element that I just created. Is there any way?
After a bit of debugging I found out that if element is a object, not string, then d3.select(element) will not look for the element in the document instead it will return the element itself.
for detailed info:
d3.select = function(node) {
var group = [ typeof node === "string" ? d3_select(node, d3_document) : node ];
group.parentNode = d3_documentElement;
return d3_selection([ group ]);
};

How to generate input select in laravel blade form and customize its options value?

I'm trying to create a laravel form that have an input select generating from array of strings coming from controller.
How can I set values of options manually?
In controller :
public function create()
{
$eventTypes = EventType::all()->lists('title');
return View::make('events.create')->with(compact('eventTypes'));
}
In view (blade) :
{{ Form::label('eventType', 'Type') }}
{{ Form::select('eventType', $eventTypes, null, array('class'=> 'form-control')) }}
And select created as :
<select class="form-control" id="eventType" name="eventType">
<option value="0">Sport Competition</option>
<option value="1">Movie</option>
<option value="2">Concert</option>
</select>
I just want to set values manually.
The value in the options is just the key of the array. The second parameter to the lists() method will let you choose a field to use as the key:
// use the 'id' field values for the array keys
$eventTypes = EventType::lists('title', 'id');
If you want to do something more custom than that, you'll need to manually build your array with the key/value pairs you want.
Edit
As mentioned by #lukasgeiter in the comments, there is no need to call all() first.
EventType::all()->lists() will first generate a Collection of all the EventType objects. It will then call lists() on the Collection object, meaning it will loop through that Collection to build an array with your requested fields.
EventType::lists() will call lists() on the query builder object, which will just select the two requested fields and return those as the array. It will not build any EventType objects (unless you select a field built by a Model accessor).