JSF Ajax question - javascript

first of all i want to excuse me for my last question. Didn`t know how the system works here :-)
I have a question cocerning JSF and Ajax.
My webapplication is dynamic. The whole page loads just one time at the beginning.
When the user navigates through the menus, just the center table changes it output.
I have some components like primeface`s datatable or just simple buttons which execute functions in my bean. My webapplication connects to a backend server and informations are shared between JSF and backend and will then be displayed to the users.
When a user clicks e.g. on the "Search" button function, the results should be displayed in my datatable. The method {#searchBean.doSearch} will be executed. A message is sent to the backend with user`s informations. After some seconds JSF receives those informations.
This is my principe.
Now i want to render manually the datatable and tell him "all search results have been received. please update the results"
Is it possible to render manually components via JSF? Or is there another solution.
And my second question.
When a message is sent to the backend it may take some seconds to receive the results,
what is the best way to display a "Waiting" message to the user (with a dialog)?
When i receive the results from my backend i want to update manually my components so the received informations will be displayed and then i need a way to remove this "Waiting" dialog.
I hope.. you understand what I want because my english is not the best :-)
I dont know how to start solving my problems... i think i just need a way to update HTML elements via JSF and render components manually. But i didnt find anything on the internet. Maybe I looked for the wrong things?
Regards,
Johnny

Since you are using Primefaces (which was built with pre-2.0 jsf in mind), you can use a more specific way of handling Ajax (than the one described by BalusC).
You will notice that most components have an attribute called "update". You use this attribute to tell JSF which components should be updated after something happens. For example if you had a button marked as:
<p:commandButton value='test' action='#{bean.search}' update='panelContainingDatatable' />
It would always refresh a component with client id of 'panelContainingDatatable' after executing bean.search() method.
Also, if you want to notify your users about an ajax request pending, use p:ajaxStatus (http://www.primefaces.org/showcase/ui/pprAjaxStatus.jsf)
Be careful, there are caveats:
we are talking about client id here, not component id (best look it up in the page sources)
there are edge cases when mixing ajax with ui:repeat and h:dataTable; frankly, it's best that you try to avoid such cases than solve them. They come from bugs in implementations and from suboptimal design decisions concerning ui:repeat.

You can use <f:ajax> for this. It has a render attribute which should point to (relative or absolute) client ID of the component you'd like to re-render. Starting with : means absolute (as it is in generated HTML), otherwise it's relative to the current naming container (like as <h:form>).
Here's a simple basic example:
<h:form>
<h:inputText value="#{bean.query}" />
<h:commandButton value="Search" action="#{bean.search}">
<f:ajax execute="#form" render=":results" />
</h:commandButton>
</h:form>
<h:panelGroup id="results">
<h:dataTable value="#{bean.results}" var="result" rendered="#{not empty bean.results}">
<h:column>#{result}</h:column>
</h:dataTable>
</h:panelGroup>
Where the Bean look like this:
#ManagedBean
#ViewScoped
public class Bean implements Serializable {
private String query;
private List<Result> results;
public void search() {
results = resultDAO.list(query);
}
// ...
}

Related

ajax json call throws ClientScriptManager.RegisterForEventValidation error; how to register?

I've been researching this like crazy, but I can't find a way to to get this error from triggering. I'm hoping someone here can help me.
I have a drop down list object on my page that I'm creating as a server control, but which I'm dealing with entirely client-side at run time. The reason why I'm using a server control at all is because I need it to trigger an AJAX updatepanel elsewhere on my page. Anyway, this dropdown list starts blank, but gets populated with options by some jquery code based on user input. Up to this point there's no problem, but when the user makes a selection from this dropdown, I get the ClientScriptManager error. Selecting from this dropdown triggers an ajax json call to get data from the server.
I'm registering all my client-side script files (including the one that contains the offending json call) with ClientScriptManager.RegisterClientScriptInclude. Registering the dropdown itself with RegisterforEventValidation doesn't work, because the dropdown has no options at load time.
The application works in spite of this, but the error is defeating some enhancements I want to make, so I need to put this to rest. You can see the application (and view the error in your browser's debugging console) at https://www.heritagecutter.com/MillingCalc/; the dropdown your looking for is the one headed "Series", which will become active after you make selections in Material Group and Material Type above. The error appears after you select a series.
Thanks in advance for any guidance.
Found a solution, for anyone who may stumble across this in the distant future:
So the situation with my code was that I was using mostly HTML objects, with ASP.NET server controls for those few instances where I was dealing with the server, even though those server controls were triggering client-side code at runtime. I did this because I are noobsauce.
I was already using client-side AJAX calls to contact the server for my data, so I cleared out the clever-clogs server controls (my offending drop down list, and the Ajax UpdatePanel in toto) and replaced them with HTML objects. I kept the .aspx page that contains my code, because I needed the code-behind to store the web methods being called by client-side script, and I left my web methods and ajax code alone, because the didn't need to be changed, and the error went away on the first try.
I go away somewhat embarrassed, but wiser for it.

Do we need AJAX in Spring MVC? When?

I am trying to learn Spring MVC and I wanted to get hands on in MVC. I have a simple web application where I am inputting a string from the user and displaying some results from a database back to the user. All this is happening in a single page without the page refresh. We can use RequestParam in the controller and access the elements in the JSP page. ( I am using Bootstrap for this project)
For example in home.jsp,
<form class="navbar-form navbar-right">
<input type="text" name="myValues" class="form-control" placeholder="product..." >
</form>
and, in the controller,
#RequestMapping(value={"", "/", "/home"}, method = RequestMethod.GET)
public String home(Locale locale, Model model,#RequestParam(value="myValues", required=false) String myValues) {
logger.info("Welcome home! The client locale is {}.", locale);
This will help me get the form query string in the controller.
I can then do the necessary processing and use addAttribute in the controller to return the list. (Retailerdetail is my class to implement the backend database)
ArrayList <RetailerDetail> rlist = mydata.getData();
model.addAttribute("name",rlist);
return "home";
and display it in the jsp page.
<c:forEach items="${name}" var="element">
<tr>
<td>${element.name}</td>
</tr>
</foreach>
At this point of time I am doing this without using Jquery or js. I have seen some code where people use jquery or js for ajax implementation in Spring MVC.
My question, is this AJAX? We are getting similar functionality as AJAX without using Javascript or Jquery. Why is jquery or js used for implementing AJAX when using Spring MVC. Can you please give a specific example where I might have to do the same? I have gone through tutorials of MVC as well as AJAX quite a bit, but dont have a complete understanding of the concept. I realize that I am missing some basic concepts here. But it will help me get a lot of clarity if you could explain.
To quote from What is AJAX, really?
This is the answer by Nosredna:
"The rough idea in English: You have a web page. Some event (can be
a button press or other form event, or just something triggered by a
timer) occurs and triggers JavaScript code that asks the server for
fresh information (like the latest value of GOOG stock). There's a
piece of code on the server that collects the info you passed and
sends some info back. That's different from the page-serving job the
server usually has. When the server answers, a callback function
(that you specified in the JavaScript call to the server) is called
with the info from the server. Your JavaScript code uses the info to
update something--like a GOOG stock chart."
In my code the same functionality is achieved without using Javascript? That means we can implement the AJAX functionality without using any Javascript? When do we really have to use Javascript for implementing AJAX in this case?
If you open developer tools in your browser (f12), open the network tab, and then perform the request from your web-page, you will see the the entire html page is returned in the response.
Using AJAX, the server will return just a JSON key-value map. Your javascript code can then use this to populate a section of your page, leaving most of the page unchanged.
This is more efficient and quicker.

Django modify model instance from HTML

I want to know if it is possible to directly modify and save a model instance in the HTML Template and not via a view and extra URL.
My user has a Boolean Property, I want to display it as a toggle button on the website and the user should be able to toggle it on or off without leaving the website or reloading it.
class User(AbstractBaseUser, PermissionsMixin):
...
autoplay_enabled = models.BooleanField(default=True)
...
Is this possible without an extra view or form?
Basically I just need to set
request.user.autoplay_enabled = False (or True)
and then save() it
If I can't modify the object directly in the HTML template is it at least possible to just execute a function I have defined somewhere in my Python code, without having the need to create a new view?
What you're asking doesn't make any sense at all. HTML is just sent to the browser for display. You can't do anything "from HTML" without making some kind of request to the server, and the server won't do anything unless that request is received by some code - eg a view connected to a URL.
If you want something to happen without refreshing the page, you need to use Ajax. You can use a simple Ajax POST to a view that toggles the value and saves it - it only needs a dozen lines of code between front and back end.

Accessing Javascript variables from JSF [duplicate]

This question already has an answer here:
How to invoke a JSF managed bean on a HTML DOM event using native JavaScript?
(1 answer)
Closed 1 year ago.
I have a JSF file that needs to get populated from the data I get from the JS function that I get from Ajax call to a web-service. The latter part works like a charm. I am able to retrieve the JSON data from the ajax call. I need to parse this json data and take data and use that to populate the JSF. I am unsure as to how I would access the JS variables from the JSF/xhtml.
Is is possible to do it in someway? I was going through some DWR stuff that would send ajax post from JS to the Java bean and I could use the bean variable from the JSF. But, I want to know if there is any other way of doing this.
I would greatly appreciate any help. I am using JSF 2.x btw.
Thanks,
S.
You can use the following 'hack' to get JS to submit information to JSF.
Create an invisible JSF form with <f:ajax> hook:
<h:form prependId="false" style="display:none;">
<h:inputText id="input" value="#{bean.input}">
<f:ajax event="change" execute="#form" listener="#{bean.process}" render=":something" />
</h:inputText>
</h:form>
Let JS update the input field and trigger the change event:
<script>
function somefunction() {
var input = document.getElementById('input');
input.value = 'your JSON string';
input.onchange();
}
</script>
Do the Java/JSF job in the listener method:
private String input; // +getter +setter
public void process(AjaxBehaviourEvent event) {
doSomethingWith(input);
}
Put the desired JSF markup in a <h:someComponent id="something"> which will be re-rendered by <f:ajax render=":something"> when the listener has done its job:
<h:panelGroup id="something">
The JSON string was: <h:outputText value="${bean.input}" />
</h:panelGroup>
That said, I'd prefer to do the webservice call in the constructor or action method of the managed bean instead of in JS. Your approach is literally a roundabout.
I think this is not possible.
JSF runs on server.
JavaScript runs on client (browser).
So, JSF runs BEFORE action in JS.
Of course, you can make a servlet that will be called from JavaScript, receiving information stored in JavaScript variables. But, this will be in next step:
JSF assembles the page
JavaScript call WebService, getting JSON data
JavaScript send JSON data to server (servlet)
You could revisit the design a bit and probably accomplish what you're looking for. Rather than accessing the webservice via ajax on the client you could access it server side by communicating with it directly in an action method or a method that occurs before the view is created (prettyfaces actions handle this kind of work nicely). Then you can construct your view dynamically based on the results of the response from the web service.
I'm not 100% sure that will accomplish what you are looking for but that general idea might work for what is sounds like you're going for.
If you've already rendered a view and you want to do it with ajax you could use f:ajax with the same principle -- hit action method, communicate with webservice server side in that action method, change state of variables that determine the view layout and render the response.

Ajax and Django forms

I'd like to add Ajax to my admin form for editing a model. The model has a list field. I would like the Ajax to create a list of inputs with add and remove buttons, automatically calling back to the server when the user clicks "add" or "remove".
What I'm stuck on is: how does the widget know what the backing model is? If it doesn't know, how can it update the values? (I would want to provide Urls like api/remove-list-item?pk=foo&item=bar to the front end.)
This makes me think that it doesn't fit with the general Django framework philosophy to be doing this. Instead, perhaps I should be keeping the values locally and sending them through the same validation process as the rest of the data. But I'm a bit unsure of how to do this.
I am doing something similar to this (although not in an admin form). I'm not sure if it is a recommended way of doing things...but it does seem to work for me.
I have an action set on a html form in the template that calls a view which basically has the sole task of updating the data in the database and returning a "success" (or whatever I happen to want it to return).
On the template side of things I also use the jquery form plugin, which I use to update the div to show the new value.
Again, I'm not sure if this is the way others would recommend, but I do feel it seems to make sense....and it does seem to work just fine.
In urls.py, make a rule like:
(r'^api/remove-list-item/(?P<id>\d+)$', 'yourApp.views.remove'),
then in the yourApp.views have something like:
from django.shortcuts import get_object_or_404, redirect
def remove(request, id):
dbObj = get_object_or_404(YourModel, id=id)
dbObj.active = False # Or whatever you want to do with the object
dbObj.save()
return redirect('some-view')
You can then make queries like /api/remove-list-item/123

Categories

Resources