Browser Back? Reload Page?

Hi

In my app the users submits a form and the results are returned, after they click search. The issue I am having, is the results are returned in the same page. So when the user clicks the back button, thinking they will return to the form, it actually returns them to the previous page in some cases they started on the form and it just reloads the page and everything is fine. But if they came to the form from somewhere else, it brings them back to that page, since it was the previous page.

Is there a way to always refresh the page if the user hits the back button from my app?

this article contains details about my app…

https://discuss.emberjs.com/t/ember-search-app/

There are at least two paths you can take here.

option 1

One is to be explicit and make the search form a different route from the search results page.

this.route('search_form');
this.route('search_results', { path: '/search_results/:query' });

When the user clicks "Search"in the search_form route, it results in a transitionTo('search_results', theUsersQuery).

The search_results route would use its model hook to actually fetch the results from an API.

option 2

In this case, you can still have a single page that is the form and the results, but you would use query parameters to store the current search query. The guides explain query parameters here: Query Parameters - Routing - Ember Guides

In this case, the user would be on /search and then after they click the button the URL would update to something like /search?query=whatever. Then if they go back, they go back to just /search.

1 Like

Thank you! I will try the 1st one and see how it goes.

The part that I get stuck on is the switching to the new route. I created a route called search_results what part of my below home.hbs (the search form) do I move to the template in the search_result route to the search-result.hbs route hbs file? Will I need anything in the search-results.js file?

here is my home.hbs

do I just add :

this.route('search_results', { path: '/search_results/:query' }); before the <table> or <div class="table-wrapper"> ??

{{!-- templates/components/home.js --}}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<div id="header" class="header1">
    <img src="assets/images/neb_logo_proces_StrainSearch.jpg" width="25%"/>
</div>
<br>
<!-- <h2 id="header2" class="header2">{{this.title}}</h2> -->
{{#if data}}
<style>
  table, th, td {
    border: 1px solid black;
  }
  th, td {
    padding: 10px;
  }
}
</style>
	<!-- <strong><font size="5">Records Found:</font></strong> -->
	<strong><font size="5">There are {{this.rowsCount}} rows matching the following criteria:</font></strong><br>	
	    <div><strong><font size="5"><u>You Searched For:</u><br>NEBID: {{this.nebid}}</font></strong>
		<br>		
        {{#if this.catalognumber}} {{this.andor2}}<u> CatalogNumber contains:</u> <strong><font size="5">{{this.catalognumber}}</font></strong> {{/if}}
		
        {{#if this.organism}} {{this.andor2}}<u> Organism contains:</u> <strong><font size="5">{{this.organism}}</font></strong> {{/if}}
		
        {{#if this.depositor}} {{this.andor2}}<u> Depositor contains:</u> <strong><font size="5">{{this.depositor}}</font></strong> {{/if}}
		
        {{#if this.productionstatus}} {{this.andor2}}<u> ProductionStatus contains:</u> <strong><font size="5">{{this.productionstatus}}</font></strong> {{/if}}
		
        {{#if this.productname}} {{this.andor2}}<u> ProductName contains:</u> <strong><font size="5">{{this.productname}}</font></strong> {{/if}}
		
        {{#if this.depositdate}} {{this.andor2}}<u> DepositDate contains:</u> <strong><font size="5">{{this.depositdate}}</font></strong> {{/if}}		
		
		<!-- removed erhost bowen 022420 -->
        <!-- {{#if this.erhost}} {{this.andor2}}<u> ER Host contains:</u> <strong><font size="5">{{this.erhost}} </font></strong>{{/if}}-->		
</div>	
	{{#if this.h_nebid}}
	
<div class="table-wrapper">
<br><br>
<!-- {{#link-to 'home'}} -->
<!-- <button type="refresh" name="reload" style="background-color:#f2661B; color:#ffffff;">Search Again</button> -->
<!-- {{/link-to}}  -->
<!-- <br><br> -->
 <table> 
    <thead>
    <tr>
	  <th>{{this.h_nebid}}</th>
      <th>{{this.h_catalognumber}}</th>
      <th>{{this.h_organism}}</th>
	  <th>{{this.h_depositor}}</th>
	  <th>{{this.h_productionstatus}}</th>
	  <th>{{this.h_productname}}</th>
	  <th>{{this.h_depositdate}}</th>
	  <!-- <th>{{this.h_erhost}}</th>	 -->
    </tr>	
  </thead> 
   <tbody>
    {{#each data as |record|}}		
      <tr>			
        <td>{{record.nebid}}</td>
        <td>{{record.catalognumber}}</td>
        <td>{{record.organism}}</td>
        <td>{{record.depositor}}</td>
        <td>{{record.productionstatus}}</td>
        <td>{{record.productname}}</td>
        <td>{{record.depositdate}}</td>
        <!-- <td>{{record.erhost}}</td>		 -->
		</tr>
	{{else}}	
	<!-- <td><font size="6"><strong>********* No records found! *********</strong></font></td>	 -->
    {{/each}}
    </tbody>
  </table>  
  </div>
  {{/if}}
{{else}}
<div>


<form class="form-style-4" id="userSubmit" {{action "search12" on="submit"}}>

<div class="form-check">
<input class="form-check-input" type="radio" name="andorRadios" id="or" checked={{this.or}} onclick={{action (mut this.or) value="target.checked"}}>
<label class="form-check-label" for="or">
    SEARCH TYPE "OR" 
</label>
</div>

<div class="form-check">
  <input class="form-check-input" type="radio" name="andorRadios" id="and" checked={{this.and}} onclick={{action (mut this.and) value="target.checked"}}>
  <label class="form-check-label" for="and">
    SEARCH TYPE "AND" 
  </label>
</div>



<br>

<!-- <label><font size="5.5">SEARCH TYPE DEFAULT: <strong>"OR"</strong>  <br>UnCheck For <strong>"AND"<span>&#8594;</span></strong></font>  -->
<!-- <input type="checkbox" style="margin-left: 30px" checked={{this.andor}} onclick={{action (mut this.andor) value="target.checked"}} > -->
<!-- </label>			 -->

<hr>	
 <!-- <div class="container">	  -->
    	<label for="nebid">NEBID:</label>
    	<input id="nebid" type="number" max="99999999" min="0" inputmode="numeric" value={{this.nebid}} oninput={{action (mut this.nebid) value="target.value"}}><br><br>
	    
		<label for="catalognumber">Catalog Number:</label>
		<!-- {{input id="catalognumber" class = "inputField" type="text" value=this.catalognumber}}<br><br> -->
		<input id="catalognumber" value={{this.catalognumber}} oninput={{action (mut this.catalognumber) value="target.value"}}><br><br>
		
		<label for="organism">Organism:</label>
    	{{input id="organism" class = "inputField" type="text" value=this.organism}}<br><br>

    	<label for="depositor">Depositor:</label>
    	{{input id="depositor" class = "inputField" type="text" value=this.depositor}}<br><br>
	
    	<label for="productionstatus">Status:</label>
    	{{input id="productionstatus" class = "inputField" type="text" value=this.productionstatus}}<br><br>

		<label for="productname">Product Name:</label>
    	{{input id="productname" class = "inputField" type="text" value=this.productname}}<br><br>

    	<label for="depositdate">Deposit Date:</label>
    	{{input id="depositdate" class = "inputField" type="date" value=this.depositdate}}<br><br>
    	
		<!-- <label for="erhost">ER Host:</label> -->
    	<!-- {{input id="erhost" class = "inputField" type="text" value=this.erhost}}<br> -->
    	<br>
		<!-- <hr> -->
		<br>
		<div>
		
		<!-- <div style="text-align: left">  -->
		<!-- <button type="submit" name="search">Search</button>  -->
		<!-- <div class="divider"/> -->
		<!-- <button type="submit" name="search">Search</button>  -->
		<!-- </div> -->		
	 

	<button type="submit" name="search" style="background-color:#f2661B; color:#ffffff;">Search</button>
	
	

	<!-- {{#link-to 'home'}} -->
	 <!-- {{/link-to}}  -->


    	 
   	 </div> 
   <!-- </div> -->
  </form>
 </div>
  
{{/if}}

Thank you for your help!

I’m assuming data is the results of running the search query? In that case, everything in the template that has to do with rendering data (probably everything inside the {{#if data}} block) moves to the search_results.hbs.

The search form itself won’t have data at all.

Will I need anything in the search-results.js file?

Assuming you mean the route file (app/routes/search_results.js), yes. The code that actually sends the query to your backend should move into that route’s model() hook.

The entire form home.hbs is inside the {{#if data}} including the search form.

so basically everything moves to the search_results route.

Then the home.hbs just calls the route search_results ?

I think I get it. So basically home.hbs is the start then we transition to the results route. So if the user hits back all it will do is go back to home which in turn goes right back to the results route?

So the search-results route should in fact be renamed something like searchANDresults or just search…

…

since home.js and home.hbs is a component.

Should my new search/results route also be a component?

Should home become a route?

so basically:

start: home route next: home route transfers to search component

Actually that didnt work. I must be missing something. or Im transferring to the search component incorrectly.

In the home.hbs

<Search @title=“Strain Search” @results={{this.model}} class=“search”/>

I’m not really understanding your setup. If you share more complete code maybe I can explain better.

Hi

here is my main search component:

search.js

import Ember from 'ember';

export default Ember.Component.extend({  

	or: 1,
	and: null,
	
	andor: "/'OR/'",	
  nebid: null,
  catalognumber: null,
  organism: null,
  depositor: null,
  productionstatus: null,
  productname: null,
  depositdate: null,
  
  actions: {
    reloadModel() {
      this.refresh();
    }
  },

  actions: {		
    search12: async function () {			
			let { andor, and, or, nebid, catalognumber, organism, depositor, productionstatus, productname, depositdate, erhost } = this;
	
	or = and ? 0 : 1;
	
	console.log('OR: ' + or);
	console.log('AND: ' + and);	
	 
	andor = or;
	console.log('andor: ' + andor);
	
	var andor2 = 'OR';	
	if(andor == 0) {andor2 = 'AND';}	
	this.set('andor2', andor2);
	console.log('andor2: ' + andor2);
	
	var whiteSpace = /^\s*$/;

	catalognumber =  whiteSpace.test(catalognumber) ? null : catalognumber;	
	organism =  whiteSpace.test(organism) ? null : organism;
	depositor =  whiteSpace.test(depositor) ? null : depositor;
	productionstatus =  whiteSpace.test(productionstatus) ? null : productionstatus;
	productname =  whiteSpace.test(productname) ? null : productname;
	depositdate =  whiteSpace.test(depositdate) ? null : depositdate;
	
	console.log('catalognumber: ' + catalognumber);	
		
	///Test with sample data...
      // let data = { andor, nebid, catalognumber, organism, depositor, productionstatus, productname, depositdate, erhost };
      // console.log(data);
      // data = Object.keys(data).map((key) => {
        // let obj = { };
        // obj[key] = data[key];
        // return obj;
      // });
      // this.set('data', data);
	  ///Test with sample data...
		
    fetch("http://localhost:3000/routes", {
        method: 'POST',				
        headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
        record: {		  
          andor,
          nebid,
          catalognumber,
          organism,
          depositor,
          productionstatus,
          productname,
          depositdate
        },		
		
		})
      }).then(res => {
        return res.json()
      }).then((data) => {		
		
		var rowsCount14 = data.rowsAffected[14];
		console.log('rowsCount14: ' + rowsCount14);
		
		var rowsCount15 = data.rowsAffected[15];
		console.log('rowsCount15: ' + rowsCount15);
		
		if (data.rowsAffected[15]) {
		var rowsCount = data.rowsAffected[15];
		} else {var rowsCount = data.rowsAffected[14]}	

		
if 	(data.recordsets[0][0].nebid)	{
		var neb_id = data.recordsets[0][0].nebid;
}
else {var neb_id = null;}

if (data.rowsAffected[15]) {
var rowsCount = data.rowsAffected[15];
} else {var rowsCount = data.rowsAffected[14];}		
	
		console.log('rowsCount: ' + rowsCount);
		console.log('nebid: ' + neb_id);		
		
		if(neb_id !== null && neb_id !== '') {		

        	this.set('h_nebid', 'NEBID');
			this.set('h_catalognumber', 'Catalog Number');
			this.set('h_organism', 'Organism');
			this.set('h_depositor', 'Depositor');
			this.set('h_productionstatus', 'Production Status');
			this.set('h_productname', 'Product Name');
			this.set('h_depositdate', 'Deposit Date');
	
		this.set('rowsCount', rowsCount);
		this.set('data', data.recordset);
		console.log('DataFound');
		console.log(data);
		
		}
      }).catch((err,data) => {

		var rowsCount = 0;
		this.set('rowsCount', rowsCount);
		this.set('data', 'no records found!');
		console.log('NoDataFound');
		console.log(data);	
	
	this.set('error', err);
	console.log('err1: ' + err);

      });
    },	
  }
});

here is the search.hbs

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">


<div id="header" class="header1">
    <img src="assets/images/neb_logo_proces_StrainSearch.jpg" width="25%"/>
</div>
<br>

{{#if data}}
<style>
  table, th, td {
    border: 1px solid black;
  }
  th, td {
    padding: 10px;
  }
}
</style>
	<strong><font size="5">There are {{this.rowsCount}} rows matching the following criteria:</font></strong><br>	
	    <div><strong><font size="5"><u>You Searched For:</u><br>NEBID: {{this.nebid}}</font></strong>
		<br>		
        {{#if this.catalognumber}} {{this.andor2}}<u> CatalogNumber contains:</u> <strong><font size="5">{{this.catalognumber}}</font></strong> {{/if}}
		
        {{#if this.organism}} {{this.andor2}}<u> Organism contains:</u> <strong><font size="5">{{this.organism}}</font></strong> {{/if}}
		
        {{#if this.depositor}} {{this.andor2}}<u> Depositor contains:</u> <strong><font size="5">{{this.depositor}}</font></strong> {{/if}}
		
        {{#if this.productionstatus}} {{this.andor2}}<u> ProductionStatus contains:</u> <strong><font size="5">{{this.productionstatus}}</font></strong> {{/if}}
		
        {{#if this.productname}} {{this.andor2}}<u> ProductName contains:</u> <strong><font size="5">{{this.productname}}</font></strong> {{/if}}
		
        {{#if this.depositdate}} {{this.andor2}}<u> DepositDate contains:</u> <strong><font size="5">{{this.depositdate}}</font></strong> {{/if}}		

</div>	
	{{#if this.h_nebid}}
	
<div class="table-wrapper">
<br><br>

<button {{on "click" (action "reloadModel")}}>Search Again?</button>


<br><br>
 <table> 
    <thead>
    <tr>
	  <th>{{this.h_nebid}}</th>
      <th>{{this.h_catalognumber}}</th>
      <th>{{this.h_organism}}</th>
	  <th>{{this.h_depositor}}</th>
	  <th>{{this.h_productionstatus}}</th>
	  <th>{{this.h_productname}}</th>
	  <th>{{this.h_depositdate}}</th>
    </tr>	
  </thead> 
   <tbody>
    {{#each data as |record|}}		
      <tr>			
        <td>{{record.nebid}}</td>
        <td>{{record.catalognumber}}</td>
        <td>{{record.organism}}</td>
        <td>{{record.depositor}}</td>
        <td>{{record.productionstatus}}</td>
        <td>{{record.productname}}</td>
        <td>{{record.depositdate}}</td>
		</tr>
	{{else}}	

    {{/each}}
    </tbody>
  </table>  
  </div>
	{{/if}}
{{else}}
<div>


<form class="form-style-4" id="userSubmit" {{action "search12" on="submit"}}>

<div class="form-check">
<input class="form-check-input" type="radio" name="andorRadios" id="or" checked={{this.or}} onclick={{action (mut this.or) value="target.checked"}}>
<label class="form-check-label" for="or">
    SEARCH TYPE "OR" 
</label>
</div>

<div class="form-check">
  <input class="form-check-input" type="radio" name="andorRadios" id="and" checked={{this.and}} onclick={{action (mut this.and) value="target.checked"}}>
  <label class="form-check-label" for="and">
    SEARCH TYPE "AND" 
  </label>
</div>

<br>

<hr>	
    	<label for="nebid">NEBID:</label>
    	<input id="nebid" type="number" max="99999999" min="0" inputmode="numeric" value={{this.nebid}} oninput={{action (mut this.nebid) value="target.value"}}><br><br>
	    
		<label for="catalognumber">Catalog Number:</label>
		<input id="catalognumber" value={{this.catalognumber}} oninput={{action (mut this.catalognumber) value="target.value"}}><br><br>
		
		<label for="organism">Organism:</label>
    	{{input id="organism" class = "inputField" type="text" value=this.organism}}<br><br>

    	<label for="depositor">Depositor:</label>
    	{{input id="depositor" class = "inputField" type="text" value=this.depositor}}<br><br>
	
    	<label for="productionstatus">Status:</label>
    	{{input id="productionstatus" class = "inputField" type="text" value=this.productionstatus}}<br><br>

		<label for="productname">Product Name:</label>
    	{{input id="productname" class = "inputField" type="text" value=this.productname}}<br><br>

    	<label for="depositdate">Deposit Date:</label>
    	{{input id="depositdate" class = "inputField" type="date" value=this.depositdate}}<br><br>
    	
    	<br>
		<br>
		<div>

	<button type="submit" name="search" style="background-color:#f2661B; color:#ffffff;">Search</button>
    	 
   	 </div> 
  </form>

 </div>
  
{{/if}}

Also there is some details as I was building it in this question:

https://discuss.emberjs.com/t/ember-search-app/

Explanation of this: “The entire form home.hbs is inside the {{#if data}} including the search form.” (also just to note: what used to be home.js /home.hbs is now search.js/search.hbs)

The loop: {{#if data}} contains: The entire app, Basically:

(Start Of If data:) {{#if data}}

results form
and
Search form


(End of if data: ) {{/if}}