scroll to the relevant item on html after serving a server call - java

I am rendering a html page with a list of things with an option to edit any one of them.
Draft:
On clicking on any of the item, makes a server call and effectively an update in the database.
Now, What i want to do is, When the list is long and the page is scrolled all the way to the bottom (for eg. ITEM 1000) and the user makes any server request,
after the page is reloaded, the user should be scrolled down at the exact item. Is this possible?
What is a good way to approach this functionality?
I am aware of anchor tag and name attribute and then posting url.com/#anchorTagName. But in case of server call, we dont provide any urls, its just a form.submit
Any suggestions are much appreciated!

Anchor tag is the best approach url.com/#anchorTagName but as you said the server doesn't provide it.
Here are some other alternatives:
1. Session attribute:
Once the server call is made and the data is loaded successfully in the DB, set a session variable. (session variable will contain tag)
In the UI using scriplet, assign the session variable to a javascript variable.
Now on page load, let the javascript to get the variable and scroll to the particular location.
example:
<script type="text/javascript">
window.onload = function() {
var scrollNow = "#<%=session.getAttribute('')%>"
window.location.href = scrollNow; // this will take to the particular element based on the ID
}
</script>
Another option, is to append the location in query string. Same way get the location and let the javascript do its part just like before :)
Another option,
In the form submit, handle the event via javascript before submitting the form.
Construct the action url dynamically with the hash tag and send it to the server.
So when the server receives it, it will ignore the anchor tag and will process the data.
When the page refershes again, the page scroll to the previous location as the anchor tag will be there in the URL :)

Related

How to automatically reload a jsp based on other page action

I have a situation that i can't handle and thats why need your help.
I have a jsp page (mention as A in below pic) where there are many rows and each of them can be edited.
At the end of the A jsp page, there is an option to print the page data.
Now, if some body clicks on the edit link/button, another page will open contain the data for that particular row and user can modify the data in the second page(i,e B).
Now, i want, as soon as the user save the B page, A page should be refreshed automatically to provid the updated data for printing.
Please guide me on how to acheive that . I'm using Spring MVC framework for the java application.
The Spring MVC way to meet your requirement is:
the Edit buttons in page A should be links calling page B with the id of the line to edit, something like Edit
the SaveAndClose button in page B should be a submit button that posts the edited values to a controller method. After server side processing, the controller method should redirect to page A. As a side effect, you use the PostRedirectGet pattern which avoids the ugly do you want to send again ... ?"
#RequestMapping(path = "...", method = RequestMethod.POST)
public String saveAndClose(...) {
...
return "redirect:/path/to/pageA";
}
Of course this will display all pages in same window.
If you want to redisplay the window containing pageA on the Save & Close from page B, still allowing the save to be known to the server, you should redirect to a special page (say pageC) that just contains javascript code asking the browser to redisplay pageA. You can either pass the name of the window containing pageA in a hidden field, or you can decide that as the programmer of the web application you know where it should be.
It can be achieved like this. Follow the steps mentioned
1] When you click on edit button in Page A, pass the id of the row to Page B as request parameter.
2]In Page B JSP receive the id of the row and store it in a hidden element.
3]Create a JavaScript function in Page A which should receive row Id and Modified data as parameter. Lets name it this function as updateRows(rowId,modifiedData). In this function write code to update the with id 'rowId' with modified data using javascript
4]Now When you click on 'Save & Close' Button in Page B. Save the data using call to server. If save succeeds then invoke the function updateRows passing it rowId stored in hidden element and modified data as parameters. This function will update the DOM with latest data.
This way you will avoid making server call to refresh the data
There is one more way if you don't want to use ajax.
In Page A define a javascript function refreshPageA(). In this function add page refreshing logic.
When you click on 'Save & Close' button in Page B save the data in server and forward to a plain jsp. In this JSP declare a onload handler. Inside onload handler add following code
opener.refreshPageA();
window.close()
This will refresh pageA and close page B window

Wicket - redirecting to the same page when browser back button is clicked

I have a web application that uses the Wicket framework. It has a form that takes user input and when submitted, redirects to another page. Once the form is submitted and the browser's back button is clicked, the previous form is retrieved from the cache with the values entered. I need to override this behavior and redirect to the latter page (keep staying on the same page) when the browser back button is pressed. Is this possible in Wicket? If so, please guide me on how to achieve this. Thank you.
Wicket handles URLs so if a previous page is requested by it's recognized by page ID that is by default added to the URL, e.g. http:/dummyexample.com?1
What I use to solve that problem is a flow engine that holds the state of model object within it. E.g. you have a model object of type MyFlow containing a field 'String currentState'. In this case if you required a wrong page, that is not belong the stage where your flow is, you can redirect to the relevant page from a controcutor or onIntialize() throwing 'RestartResponseException' that causes redirect to the new page.
Just use an Ajax submit, this way the user cannot return to the input form via back-button.

Easiest way to "browse" to a page and submit form in Java

What I need to do is browse to a webpage, login, then browse to another webpage on that site that requires you to be logged in, so it needs to save cookies. After that, I need to click an element on that page, in which I would fill out the form and get the message that the webpage returns to me. The reason I need to actually go to the page and click the button as suppose to just navigating directly to the link is because the you are assigned a session ID every time you log in and click the link, and its always different. The button looks like this, its not a normal href link:
<span id=":tv" idlink="" class="sA" tabindex="0" role="link">Next</span>
Anyway, what would be the easiest way to do this? Thanks.
Update:
After trying HTMLunit, and other headless browser libraries, it doesnt seem that its happening using anything "headless." Another thing that I recently found out about this page is that that all the HTML is in some weird format... Its all inside a script tag. Here is a sample.
"?ui\x3d2\x26view\x3dss\x26mset\x3dmain\x26ver\x3d-68igm85d1771\x26am\x3d!Zsl-0RZ-XLv0BO3aNKsL0sgMg3nH10t5WrPgJSU8CYS-KNWlyrLmiW3HvC5ykER_n_5dDw\x26fri"],"http://example.com/?ctx\x3d%67mail\x26hl\x3den",,0,"Gmail","Gmail",[["us","c130f0854ca2c2bb",[["n"],["m","New features!"],["u"],["k","0"],["p","1000:500000,10,200000,5,100000,3,75000,2,0,1"],["h","https://survey.googleratings.com/wix/p1679258.aspx?l\x3d1033"],["at","query,5,contacts,5,adv,5,cf,5,default,20"],["v","https://www.youtube.com/embed/Ra8HG6MkOXY?showinfo\x3d0"],
When I do inspect element on the button, the HTML code that I posted above for the button comes up, but not when doing view source. Basically, what I am going to need to do is use some sort of GUI and have the user navigate to the link and then have the program fill out the info. Does anyone know how I can do this? Thanks.
Have a look at the 5 Minute Getting Started Guide for Selenium: http://code.google.com/p/selenium/wiki/GettingStarted
On the login page, look at the form's HTML to see the url it posts to and the url parameters. Then request that url with the same parameters filled in with correct info, and make sure to save all the cookie headers to send to the second page. Then use an html parser to find your link. There are several html parsers available on sourceforge, and you could even try java's built in xml parsers, though if the site has even a tiny html mistake they will glitch.
EDIT didn't notice the fact that it is not a normal link. In that case you will need to look at the site's javascript to see where the link leads. If the link requires javascript to run, it gets more complicated. Java is not able to execute browser javascript, but I found a library called DJ native swing which includes a web browser class that you can add to jframes. It uses your native browser to render, and to run javascript.
This should be possible in Selenium as others have noted.
I have used Selenium to login then crawl a site and discover every permuation of values for every form on the site (30+ forms). These values are later used to fill and submit the form with a specific perumation of values. This site was very JS/jQuery heavy and I used Selenium's built-in support of javascript executor, css selectors, and XPath to accomplish this.
I implemented HtmlUnit and HttpUnit as faster alternatives, but found they were not as reliable as Selenium given the JS semantics of the site I was crawling.
It's hard to give you code on how to accomplish it because your Selenium implementation will be quite page-specific and I can't look at the page you're coding against to figure out what's going on with that button script junk. However, I have include some possibly relevant selenium code (Java) snippets:
Element element = driver.findElements(By.id(value)); //find element on page
List<Element> buttons = parent.findElements(By.xpath("./tr/td/button")); //find child element
button.click();
element.submit() //submit enclosing form
element.sendKeys(text); //enter text in an input
String elementText = (String) ((JavascriptExecutor) driver).executeScript("return arguments[0].innerText || arguments[0].textContent", element); //interact with a selenium element via JS
If you are coding similar functions on different pages, then PageObjects behind interfaces can help.
The link Anew posted is a good starting point and good ol' StackOverflow has answers to just about any Selenium problem ever.
Instead of trying to browse around programmatically, try executing the login request and save the cookies then set those in the next request to the form post.
HTMLUnit is pretty bad at processing JavaScript, the Rhino JS library produces often errors (actually no errors is much the exception). I would advise to use Selenium, which is basically a framework to control headless browsers (chrome, firefox based).
For your question, the following code would do the work
selenium.open(myurl);
selenium.click("id=:tv");
You then have to wait for the page to load
selenium.waitForPageToLoad(someTime);
I would recommend htmlunit any day. It's a great library.
First, check out their web page(http://htmlunit.sourceforge.net/) to get htmlunit up and running. Make sure you use the latest snapshot(2.12 when writing this)
Try these settings to ignore pretty much any obstacle:
WebClient webClient = new WebClient(BrowserVersion.FIREFOX_17);
webClient.getOptions().setRedirectEnabled(true);
webClient.getOptions().setCssEnabled(false);
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
webClient.getOptions().setUseInsecureSSL(true);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.getCookieManager().setCookiesEnabled(true);
Then when fetching your page, make sure you wait for background Javascript before doing anything with the page, like posting a login form:
//Get Page
HtmlPage page1 = webClient.getPage("https://login-url/");
//Wait for background Javascript
webClient.waitForBackgroundJavaScript(10000);
//Get first form on page
HtmlForm form = page1.getForms().get(0);
//Get login input fields using input field name
HtmlTextInput userName = form.getInputByName("UserName");
HtmlPasswordInput password = form.getInputByName("Password");
//Set input values
userName.setValueAttribute("MyUserName");
password.setValueAttribute("MyPassword");
//Find the first button in form using name, id or xpath
HtmlElement button = (HtmlElement) form.getFirstByXPath("//button");
//Post by clicking the button and cast the result, login arrival url, to a new page and repeat what you did with page1 or something else :)
HtmlPage page2 = (HtmlPage) button.click();
//Profit
System.out.println(page2.asXml());
I hope this basic example will help you!

How to update some components of my JSP page using JavaScript

I have a Jsp page and I want automaticly update one of the form on it using Js. Can somebody suggest something
Thanks)
You can dynamically update the elements of the form using basic JavaScript, if thats what you are looking for. Here are some dirty examples:
Eg.
If the id of your form is myForm, you can use
document.forms["myform"].action = "somepage"; //to change the action
var elem1 = document.getElementById("elementID")` //to get an element
var elem2 = document.forms["myform"].element //other way to get an element
childElement = document.createElement("option"); //to create a new element
myform.appendChild(childElement); //to append some child-element to the form
etc. The values/attributes/styles can be changed for the elements too using simple JavaScript. Any JavaScript tutorial on the internet should be helpful.
Have a look at the jQuery library (http://jquery.com/), that will allow you to manipulate HTML elements on the page, including the form element and it's children to automatically update them however you please :)
For an update from server side i.e Data from database or some other file on server use ajax
Now it depends on you to go for javascript or jquery to make this work.
Google this you can find good solutions.

Display page data on same page without forwarding it to another page

In my webpage (Eg Link1: http://localhost:8086/MyStrutsApp/login.do) I have several links. When a user clicks on one of the links, he is taken to another page (Eg link2: http://localhost:8086/MyStrutsApp/AddBook.jsp) to fill an html form.
Now what I want to achieve is that when any user clicks on the link, that html form (Link2) is displayed on the same page (i.e. Link1).
I have no idea how to achieve this.
The AJAX way to achieve this is the following:
you have a DIV on your original page that will be replaced (i.e., either has content that only makes sense in the original context or completely empty)
your Link2 servlet produces only the contents of the above DIV (and not the contents of that page)
you use a tiny bit of Javascript to make an AJAX call and fill the DIV with the response.
If you want to use Dojo, the HTML page would look like this:
<!-- main content -->
<div id="leftpanel">
<h3>This content will be replaced</h3>
You can add a book
</div>
The Javascript code would look like this:
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js" type="text/javascript"></script>
<script type="text/javascript">
function display_wait(s) {
var mainPanel=dojo.byId("leftpanel");
mainPanel.innerHTML='<div class="waitingmsg">'+s+'</div>';
}
function updateFromURL(url) {
display_wait("loading content");
dojo.xhrGet({url:url,
load:function(result) {
dojo.byId('leftpanel').innerHTML=result;
}});
}
</script>
(As Rafa mentioned, you can use the same technique to display the new part in a dialog)
You can always use jQuery to present a dialog ... http://jqueryui.com/demos/dialog/
Retrieve the page with AJAX and present it inside the dialog.
To display one page within another, use an iframe. See the iframe docs.
To make a link on the outer page load its target page into the iframe, give the iframe a name attribute, and give the link a matching target attribute.

Categories

Resources