[SOLVED] How to get Instance of Virtual List and update Items?

Hi, I’m trying to get the instance of a virtual list and update it with new items, but the method returns undefined. I’d like to populate a list instead of a user choice. The items of the list are retrieved from a get request.
In my page I have a Calendar picker and a search button. Firstly the user set a value from the calendar and then click to the button search. The button click executes the request and after retrieved the items I’d like to show the list in the same page…
I know that the virtual list to work should be create in the pageInit event. For this I created firstly an empty virtual list instance on pageInit and than I’m trying to populate it.

This is my html page

   <div data-name="an-results" class="page">
   <div class="navbar color-theme-green">
	<div class="navbar-inner sliding">
		<div class="left">
			<a class="link panel-open">
				<i class="f7-icons ios-only">menu</i>
				<i class="material-icons md-only">menu</i>
			</a>
		</div>
		<div class="title">Search</div>				
	</div>
</div>	
<div class="page-content">
	<div class="row justify-content-center">
		<div class="col-100 tablet-100 desktop-90">
			<div class="card head-card-forest">
				<div class="card-header"><h2> Search</h2></div>
				<div class="card-content card-content-padding">	
				
					<div class="row">
						<div class="col-100 tablet-100 desktop-50">
							<div class="list no-hairlines">
								<ul>
									<li id="data">
								      <div class="item-content item-input">
								        <div class="item-inner">
								        <div class="item-title">Search by</div>
								          <div class="item-input-wrap">
								            <input name="data" type="text" placeholder="" readonly="readonly" id="history-calendar-modal"/>
								          </div>
								        </div>
								      </div>
								    </li>
								</ul>
							</div>
						</div>
					</div>
				</div><!--card-content-->
				<div class="card-footer margin padding" id="footer-card-history">
					<span></span>
					<div class="col-100 tablet-50 desktop-30">
						<a class="button button-fill" href="#"  id="button-search">Search</a>
					</div>
				</div>		
			</div><!--card-->								
		</div><!--col-100-->		
	</div><!--row-->
	<div class="row justify-content-center"> 
		<div class="col-100 tablet-100 desktop-90">
	    	<div class="card">
				<div class="card-content card-content-padding">										    
				    <div class="list links-list virtual-list  searchbar-found padding history-list"></div>
				</div><!--card-content-->
			</div><!--.card-->
		</div>				
	</div><!--row-->		
</div> <!-- ./ page-content-->

this is my code in app.js where I init the vl instance

{

				name: 'an-history-list',
				path: 'history-list/',
				url: './pages/an/history-list.html',
				on: {
						pageInit: function(e,page){ 
									/**create Calendar instance**/
									utils.loadCalendar();
									/**create Empty virtual list**/
									utils.loadEmptyVlist('.history-list');
									
								}

									
					}
			},

This is the method where I create the Virtual list instance

utils.loadEmptyVlist = (inputElement) =>{
var vlHistory= app.virtualList.create({
					inputEl: inputElement,
					items: [],
					itemTemplate:
						'<li>'+
						  '<a class="item-link item-content" {{href}}>'+
						      '<div class="item-inner">'+
						       ' <div class="item-title-row">'+
						        '<div class="item-title">Item n° {{id}}</div>'+
						        '<div class="item-after">{{ora_mod}}</div>'+
						        '</div>'+
						        '<div class="item-subtitle">Data: {{data_mod}}</div>'+
						      '</div>'+
						    '</a>'+
						  '</li>',
					height: app.theme === 'ios' ? 63 : 73

					});
}

This is the method that is called when the user clicks on the search button and where I’m trying to get the VL instance to populate the array.

  app.request.get(    url, 
	            {
	              keys: key,
	              id: id,
	              where: query,
	              from: scheda
	            },
	            
	            function(data){

	              var d = JSON.parse(data);

	              switch(d.response.code)
	              {
	                case '400':  
	                            app.preloader.hide();                        
	                            app.dialog.alert('Error get request');
	                            break;

	               

	                case '200':
	                		   app.preloader.hide();
	                           console.log(d.data);
	                           /**Creates the array**/
	                           var items = [];

								for (var i = 0; i < d.data.length; i++) {  

								    items.push({id: d.data[i].id , data_mod: utils.convertDigitIn(d.data[i].data_mod) , ora_mod: d.data[i].ora_mod, href: 'href=\'/anagrafica/history-view/?id=' + JSON.stringify(d.data[i].id) + '"\''});
								    console.log(items[i]);
								}
								/**THIS IS WHERE I'M TRYING TO GET THE INSTANCE BUT THE CONSOLE WRITE:
								TypeError: undefined is not an object (evaluating 'vl.appendItems')
								 **/
							    var vl = app.virtualList.get('.history-list');
							    vl.appendItems(items);                                          
	                            break;
	                
	                
	              }//switch
	        
	      });//request

when pageInit,list never created n mounted in dom.pagemounted is right event

Hi thank you for reply, I changed

pageMounted: function (e, page) {
						    //console.log('page mounted');
						    utils.loadEmptyVlist('.history-list');
						},

but the problem remains

@nolimits4web can you help me? Where is the mistake? I always created the vl instance on pageInit event

create in pagemounted with param {el: element,…}

1 Like

It works! thank you so much… can I ask you why the correct event to create a component as VL is pageMounted and not pageInit?

as long as you doing it correctly
you can create it any time you want

anyway:
the preferred time is on pageInit

1 Like

I don’t think so. If you’re used to wysiwyg coding, you’ll often forget to re-initialize or re-render the object-to-object mapping binding. There is no way to capture this and it can be very confusing. F7 is not a data binding framework, at least not in that regard.I strongly recommend create VL in pageMounted!

Here is what is the difference between pageMounted and pageInit events.

  1. When page mounted (added to DOM), pageMounted fires.
  2. Then Framework7 does a bunch of internal scripts for page components. For example it can add some extra HTML elements for range slider, preloader, etc.
  3. Then pageInit happens when F7 done its job.

So between pageMounted and pageInit events, HTML markup and structure can change a bit. So the safest way is to init it on pageInit. Also if use keepAlive route then pageMounted can happen multiple times on same page that will cause issues if you have VL here and you will init same VL multiple times

1 Like

Thank you Vlladimir for the explanation. So, generally, the safest way for create a components is to init it on pageInit.