angular 5 how to generate dynamic key element in formBuilder.group object - angular5

I am try to iterate list of input fields based on my initial http response object.
I am using reactive form in my application, so while iterating objects of form element in ui how to generate the dynamic key in my formBuilder.group object ?
so that it will easy to handle all my form element data while submitting as like when we keep if its static data.
Please refer below noted stackblitz:
// service response data
this. formData=[
{name: krish, email: test#gmail.com},
{name:anand, email: teat2#gmail}
]
// how to generate dynamic key in formbuilder group object ?
this.homeDetails = this.formBuilder.group({
krish:['', Validators.required],
anand:['', Validators.required]
});
above forBuilder group object how to iterate and set the key values of krish/anad dynamically? Is that any way to generate like for loop FormBuilder.group the object with key since it’s based on service response dynamic..?
Refer URL:
https://stackblitz.com/edit/angular-router-example-dynamic-formcontrolname-rtmsqz?file=app%2Fhome%2Fhome.component.ts

Try this one. this will works
*Declare formgroup variable*
homeDetails: FormGroup;
// service response data
this. formData=[
{name: krish, email: test#gmail.com},
{name:anand, email: teat2#gmail}
]
this.homeDetails = this.fb.group({});
let formControlFields = [];
for (let k = 0; k < this.formData.length; k++) {
formControlFields.push({ name: this.formData[k].name, control: new FormControl('', Validators.required) });
}
formControlFields.forEach(f => this.homeDetails.addControl(f.name, f.control));

Related

Kendo UI autocomplete dynamically loading dBdata when typing

I am writing a kendo UI autocomplete widget. The requirement is EACH TIME when I type a letter after "minLength", the dataSource need to be dynamically loaded from dB EVERYTIME. One problem is that, when the dataSource load successfully in the first time, it stops loading data.
The code snippet is:
var data;
function getDataFromDb(){
// some code to grab dummyData from dB ...
return dummyData;
}
$("#someInputText").kendoAutoComplete({
minLength: 2,
dataTextField: "someField",
dataSource: getDataFromDb(),
filter: "startswith"
});
Thanks a lot.
More details on the post. In my situation, I don't use the readOption. The data comes from another ajax call like:
var data [];
//fire this ajax call when input string length comes to 4...
$.ajax({url: "some working url", success: function(result){
var data = result;
startKendoAutoComplete();
}
});
function startKendoAutoComplete(){
if( !$.isEmptyObject(data)) // set a breakPoint, have data
{
$("#inputText").kendoAutoComplete({
minLength: 4,
dataSource : data,
...
});
}
}
Also, the ajax call will be fired when the input string length comes to 4. However, the KendoAutoComplete doesn't start working....
Thanks a lot for your sugesstion.
If you init your dataSource with an array of object, your widget will work with this array only.
The first thing you'll have to create an dataSource object and set the serverFiltering property to true. Then, if you don't specify an url where the data will be fetched, you set you own transport.read function and from there you'll be able to implement your own logic. The read function will receive the readOption which will include all the relevant information to query tour data (top / skip / filter / sort ...). The readOptions will also provide a success function that should be used to return the value:
dataSource: {
serverFiltering: true,
transport: {
read: function (readOptions) {
readOptions.success(getDataFromDb(readOptions));
}
}
},

Pass data-attribute value of clicked element to ajax settings

For an implementation of Magnific Popup, I need to pass a post id to the ajax settings. The post id is stored in a data attribute of the element to which Magnific Popup is bound. I would like this to work:
html element:
<a data-id="412">Clicke me</a>
Javascript:
$('.element a').magnificPopup({
type: 'ajax',
ajax: {
settings: {
url: php_array.admin_ajax,
type: 'POST',
data: ({
action:'theme_post_example',
id: postId
})
}
}
});
Where postId is read from the data attribute.
Thanks in advance.
$('.element a').magnificPopup({
callbacks: {
elementParse: function(item){
postData = {
action :'theme_post_example',
id : $(item.el[0]).attr('data-id')
}
var mp = $.magnificPopup.instance;
mp.st.ajax.settings.data = postData;
}
},
type: 'ajax',
ajax: {
settings: {
url: php_array.admin_ajax,
type: 'POST'
}
}
});
Here is how to do it:
html:
<a class="modal" data-id="412" data-action="theme_post_example">Click me</a>
jquery:
$('a.modal').magnificPopup({
type: 'ajax',
ajax: {
settings: {
url : php_array.admin_ajax,
dataType : 'json'
}
},
callbacks: {
elementParse: function() {
this.st.ajax.settings.data = {
action : this.st.el.attr('data-action'),
id : this.st.el.attr('data-id')
}
}
},
parseAjax: function( response )
{
response.data = response.data.html;
}
});
php
function theme_post_example()
{
$id = isset( $_GET['id'] ) ? $_GET['id'] : false;
$html = '<div class="white-popup mfp-with-anim">';
/**
* generate your $html code here ...
*/
$html .= '</div>';
echo json_encode( array( "html" => $html ) );
die();
}
As this answer was the original question regarding inserting data into Magnific's ajax call, I'll post this here.
After many hours of trying to figure this out, you should know that if you're using a gallery with the ability to move between gallery items without closing the popup, using elementParse to set your AJAX data will fail when you visit an item after already viewing it (while the popup is still open).
This is because elementParse is wrapped up in a check that it makes detect if an item has already been 'parsed'. Here's a small explanation as to what happens:
Open gallery at item index 2.
Item has not been parsed yet, so it sets the parsed flag to true and runs the elementParse callback (in that order). Your callback sets the ajax options to fetch this item's data, all is well.
Move (right) to item index 3.
Same as above. The item has not been parsed, so it runs the callback. Your callback sets the data. It works.
Move (left) back to item index 2.
This time the item has been parsed. It skips re-parsing the item's element for assumed potential performance reasons.Your callback is not executed. Magnific's ajax data settings will remain the same as if it were item index 3.
The AJAX call is executed with the old settings, it returns with item index 3's data instead, which is rendered to the user. Magnific will believe it is on index 2, but it is rendering index 3's data.
To resolve this, you need to hook onto a callback which is always executed pre-ajax call, like beforeChange.
The main difference is that the current item isn't passed through into the callback. Fortunately, at this point, magnific has updated their pointers to the correct index. You need to fetch the current item's element by using:
var data = {}; // Your key-value data object for jQuery's $.ajax call.
// For non-closures, you can reference mfp's instance using
// $.magnificPopup.instance instead of 'this'.
// e.g.
// var mfp = $.magnificPopup.instance;
// var itemElement = mfp.items[mfp.index].el;
var itemElement = this.items[this.index].el;
// Set the ajax data settings directly.
if(typeof this.st.ajax.settings !== 'object') {
this.st.ajax.settings = {};
}
this.st.ajax.settings.data = data;
This answer can also be used as a suitable alternative to the currently highest voted, as it will work either way.
You may use open public method to open popup dynamically http://dimsemenov.com/plugins/magnific-popup/documentation.html#public_methods
postId = $(this).attr('data-id')
$(this) retrieve the current element (the link you clicked on), and attr the value of the specified attribute.

Manipulating datastore data after loading

I have a backend that returns some JSON data that is used by my datastore through an ajax proxy. The data is then displayed in a dataview. What I need to do is perform some transformation on the received data on client side before it is displayed by the dataview.
I tried various approaches and settled on attaching a handler to the datastore's load event:
Ext.getStore('MyStore').on('load', function (store, records, successful, operation, eOpts) {
for (var i = 0; i < records.length; i++) {
var e = records[i];
e.data.myField = "constantPrefix" + e.data.myField;
}
});
The handler fires and records are changed correctly.
Problem is, the dataview still shows unchanged data. Is the whole approach correct? If so, why's it not working; if not - how would you achieve that?
Below is the dataview code:
Ext.define('MyProject.view.MyDataView', {
extend : 'Ext.DataView',
xtype : 'my-dataview',
config : {
store : 'MyStore',
baseCls : Ext.os.deviceType === 'Phone' ? 'my-dataview-phone' : 'my-dataview-tablet',
mode: 'MULTI',
allowDeselect: true,
selectedCls: 'tick-visible',
triggerEvent: 'itemdoubletap',
itemTpl : [
'<img class="my-photo my-dataview-photo" src="',
'{myField}"></img>'
].join('')
}
});
instead
e.data.myField = "constantPrefix" + e.data.myField;
use
var value = "constantPrefix" + e.get('myField');
e.set('myField', value);
model.set() is responsible to trigger necessary events, which the dataview does catch.
cheers, Oleg
You just need to inform the store listeners about the modified fields. Try:
Ext.getStore('MyStore').afterEdit(e, ['myField']);
This has the advantage, that the dataview or grid will now show the fields as modified (with these red triangles in the field).

Simple store connected list for dojo

Is there a simpler list type than DataGrid that can be connected to a store for Dojo?
I would like the data abstraction of the store, but I don't need the header and cell stucture. I would like to be more flexible in the representation of the datalines, where maybe each line calls an function to get laid out...
You ask a really good question. I actually have a blog post that is still in draft form called "The DataGrid should not be your first option".
I have done a couple thing using the store to display data from a store in a repeated form.
I have manually built an html table using dom-construct and for each.
var table = dojo.create('table', {}, parentNode);
var tbody = dojo.create('tbody', {}, table); // a version of IE needs this or it won't render the table
store.fetch({ // this is a dojo.data.ItemFileReadStore, but you cana dapt to the dojo.Store API
query: {},
onComplete: function(itms) {
dojo.forEach(itms, function(itm, idx) {
var tr = dojo.create('tr', {}, tbody);
// use idx to set odd/even css class
// create tds and the data that goes in them
});
}
});
I have also created a repeater, where I have an html template in a string form and use that to instantiate html for each row.
var htmlTemplate = '<div>${name}</div>'; // assumes name is in the data item
store.fetch({ // this is a dojo.data.ItemFileReadStore, but you cana dapt to the dojo.Store API
query: {},
onComplete: function(itms) {
dojo.forEach(itms, function(itm, idx) {
var expandedHtml = dojo.replace(htmlTemplate, itm);
// use dojo.place to put the html where you want it
});
}
});
You could also have a widget that you instantiate for each item.

insert in sencha touch data store

Could someone please explain how the insert works to add a record in a datastore
with tha fields: "title", "info" and "price"?
because i tried some things and none of them work. and the sencha website doesnt make it very clear.
Adding a new item to an existing Store isn't that hard actually.
First of you will need to configure your model and store. In your question you name the fields 'title, 'info' and 'price'.
Model:
Ext.regModel('myModel', {
fields: [
{name: 'id', type: 'int' },
{name: 'title', type: 'string' },
{name: 'info', type: 'string' },
{name: 'price', type: 'int' }
]
});
Next you configure the store that will hold the data, based on the above model. I think that, in your case, it should be a model without any data preloaded via, for example, JSON?
So lets make a localstorage (empty store). The Store consists of the model (myModel), you give it a storeID (so that you can later on reference the store by this ID). The proxy is localstorage and the unique ID of the Store will be the ID field of the Model.
Store:
var myStore = new Ext.data.Store({
model: "myModel",
storeId: "myStoreID",
proxy: {
type: "localstorage",
id: "id"
}
});
Now, suppose you have some kind of Form (in which the user can add input a title, info and price, and you want to add these items to the existing store on submittal.
Within the handler of the submittal button you now have to 'call' the store, and perform the add function on it. Within this add function you will have to define the params (the model params) and the data to insert.
Below I have used a mixture of fixed data and a variable to insert.
myStoreID.add({ title: "Mijn Titel", info: "Informatie, price: prijsvar });
The store will now be filled will now be filled with an extra data-record which you can use. Lets say for example that the store is attached to a dataview, then you can perform:
dataView.update();
The above isn't a full tutorial, but I think this will help you along?
Just an update of the YDL answer.
As per the dataView should be related to the updated store, the last sentence dataView.update() should not be needed, due to the automatic update of the views related to a store when it change.
new Ext.DataView({
store: MyStore,
itemSelector: 'div.thumb',
tpl: thumbTpl
});
later, if I do the following, the new item should be displayed in views (List, DataView, etc.) that have MyStore as store.
MyStore.add(newItem);
HTH.
Milton Rodríguez.
If you are trying to pass in an object that was returned from a getValue() on your form, make sure that you run a
myStore.sync();
after you have called the add() method, or you wont see it in your browsers local store.
It is Very easy try these
// first get those values and store in locally
var A_select1=Ext.getCmp('select1').getValue(); // get value
localStorage.setItem("Adult1_select1",A_select1); // set localStore
var AdultSalutation={
'Adult1_select1':A_select1, // assign the value
};
var AdultSalutationstore = Ext.getStore('Adult_AdultSalutationstore'); // get store
AdultSalutationstore.add(AdultSalutation); // add object
AdultSalutationstore.sync(); // sync
AdultSalutationstore.load(); // load