Dependable drop down list in JSP, Struts2 - struts2

i am working on a project and using Struts2 for it with JSP. In one JSP page, i have two drop down list say dd1 and dd2. The dd2 is dependable on dd1. The values in dd2 should be populated based on the dd1 value. Now i have a java class which gives me all the options for the drop down lists from the database and i am displying them in my JSP using the SELECT tag. How to make the dd2 dependable on dd1? I dont have any knowledge of Ajax. Please help.

Not a very big fan of any Ajax plugin.If you do not want to use any big fancy Ajax tags and are ready to learn a bit of JQuery or any other java-script framework, i suggest you to use simple ajax call.
Play around with the events when the value in your parent drop-down change call a function and make an Ajax call to your action which can return the values in JSON format (use struts2 JSON plugin), parse the JSON data and fill the other drop-down.
benefits of this approach are
More flexible.
Much light and faster.
No need to add any UN-necessary dependencies. Other approach (IMO not the good one) use Struts2-Jquery plugin to get it done but get ready for any undesirable behavior or any other issue and you have to reply on the Plugin community.
Here is an example as suggested
<s:select list="states" label="State" name="state" onchange="ajaxCallForDistrict();"
id="stateList"></s:select>
<s:select list="districts" label="District" name="district" id="district" />
what i am doing here is that District are dependent upon state so once user select a State from first select i am calling a java-script function on onchange event and here is my ajaxCallForDistrict() function
function ajaxCallForDistrict()
{
var selectedState = document.getElementById("stateList");
var statedata = selectedState.options[selectedState.selectedIndex].value;
var formInput='state='+statedata;
$.getJSON('search/getDistricts',formInput,function(data) {
$('.result').html('' + data.districts + '');
$.each(data.districts,function(index, value){
var districtid = document.getElementById("district");
var option=new Option(value,value);
try{
districtid.add(option);
}
catch(e){
districtid.appendChild(option);
}
});
});
}
what i am doing in above function is that i am fetching the value of selected state and giving the Ajax call to getDistricts Action which is simply creating a list of district for the provided state and returning back the result as JSON data.
for filling the District select i am looping through the result (JSON) and appending the element in the select box

JSP are servlets inside so there no way how to make interaction after response is send to client
i would recommend struts2-jquery-plugin - you will be able to solve this problem using ajax and this framework is good place to start if you are not interested in learning javascript (jQuery), showcase

I am not sure but may be this can help you...
jsp page
<s:select name= "" lable = "" onchange="javaScriptFunction(element that you have selected);"></s:select>
JavaScript---
<script>
function javaScriptFunction(element)
{
document.LoginForm.action=element+".action";
document.LoginForm.submit();
}
</script>
Now map these action in struts.xml
My suggestion is use one action but several different methods.
After that populate the other dropdown Box by using s:iterator.

Related

Saving Cascading drop downs in MVC

I have cascading dropdowns in my MVC partial view. DD1 drives the values in DD2. When I select DD1 I want DD2 to be populated with, based on a DB table, the correct values based on DD1's value.
My thought was to make DD2 a partial view and nest in my form. Then, with ajax, I can tell the partial view to refresh and pass it the value of DD1.
The problem is, when I submit the whole view (with both DD1 and DD2 and a bucnh of other stuff, how do I get the value that is in DD2?
I'm trying to solve this problem using MVC, rather than triggering a javascript function on change of DD1 to make a JSON call to get the options and then using javascript to modify DD2 to the correct values.
How should I do this?
How big are your value sets for each drop down?
I was attempting to do this same thing a few years ago. DD1 was United States and Canada, and DD2 was the associated States and Provinces. If your data set is relatively small, you're better off just putting all the select list markup for both cases in the page, and then swapping it out with javascript (jQuery). You'll be saving yourself the request round trip, regardless of whether you go ajax or a full page refresh.
If the data set is large and it doesn't make sense to put all values in the markup, and you want to use MVC views instead of modifying the DOM with an ajax call, then just refresh the entire page. If you want to go ajax, then just modify the DOM with jQuery; you don't need a partial view to accomplish this.
You are going to have to use javascript unless you want to do an entire page postback. For this type of thing, javascript/ajax is the way to go. I personally had a hard time when I switched to MVC having to accept that all this business logic was happening outside of the MVC model. But in the end, it's whatever makes the website work best (user doesn't see your code and know how pretty it is).
Anyway, partials won't work either unless you post the whole page since without using javascript, the partial is rendered as part of that page/form.
I would just add a onchange event to the first dropdown that triggers a json call to a method in the same controller...something like
...jquery...
$("#mydropdown").change(function() {
$.post("/Controller/DropdownChangedJSON", { firstdropdownvalue: $("#mydropdown").val() }, function(data) {
$("#seconddropdown").empty();
// loop through "data" to populate dropdown
}); //post
}); //mydropdown_change()
and in your controller:
public JsonResult DropdownChangedJSON(string firstdropdownvalue) {
//get results
List<datamodel> myarray = //something
return new JsonResult { Data = new { success = true, rows = myarray } };
}
hope this helps

"Next" Button disabled until values are selected and typed in DropDownLists and Textboxes in MVC?

I am using MVC-Viewmodel, EF model first on my project.
I have 3 DropDonLista and a few TextBoxes in my View, User can select Values in the DropDownLists and Type inside the TextBoxes. I want that my "Next" button is disabled until values are selected and textboxes are filled then it gets enabled.
How can I easiest way accomplish this?
I've done this kind of things with C# Winforms and its pretty easy but in MVC I have no clue how I can do this.
Thanks in Advance!
You would need to use a client side scripting language like JavaScript. JQuery (a framework to make JavaScript easier to use) is now integrated in to MVC3+, so implementing it is much easier than it has been in the past.
You can target HTML DOM elements (HTML tags in your page, in layman terms) in jquery using "selectors" - i.e. if you want to access a HTML textbox called "test" in your form, and check the value, you can do the following:
var value = $("#test").val();
if(value == '') {
// do something
}
JavaScript syntax is strikingly similar to C#, but it works on the client side (it's processed by the browser), rather than the server.
you can use javascript/jquery to check if values are selected and textboxes are filled then enable the next button.

JSF2 + IceFaces 2 - Retrieve UIComponent from ViewRoot

I've got hard time resolving the following. My problem is quite simple : I would like to highlight in red the forms fields that triggered validation errors. The error messages are placed correctly in the FacesContext using a context.addMessage(...) line.
I'd like my system to be generic. All form fields having a message attached are automatically highlighted.
I've found on this site a link to this excellent article :
http://www.jroller.com/mert/entry/how_to_find_a_uicomponent
With it, I did implement a PhaseListener for the RENDER_RESPONSE phase, which do the following :
#Override
public void beforePhase(PhaseEvent event) {
// get context
FacesContext context = event.getFacesContext();
// iterate on all the clientIds which have messages
Iterator<String> clientIdsWithMessages = context.getClientIdsWithMessages();
while (clientIdsWithMessages.hasNext()) {
// get the clientId for the field component
String clientIdWithMessage = clientIdsWithMessages.next();
// split on ":"
String[] splitted = clientIdWithMessage.split(":");
UIComponent component = findComponentInRoot(splitted[splitted.length - 1]);
if (component != null) {
Map<String, Object> attributes = component.getAttributes();
if (attributes.containsKey("style")) {
attributes.remove("style");
}
attributes.put("style", "background-color: #FFE1E1;");
}
}
}
This perform perfectly well for almost all my usage.
Now, where it becomes a bit tricky, is that some of my forms have such code :
<ice:dataTable id="revisionDocuments" value="#{agendaBean.agenda.revisionsDocuments}" var="revision">
<ice:column>
<ice:inputText value="#{revision.sequenceAdresse}" id="revisionSequenceAdresse" />
</ice:column>
....
The generated form has several lines (one for each object of the revisionsDocuments list), and each element has a unique identifier (clientId) which looks like :
contentForm:revisionDocuments:0:revisionSequenceAdresse
With 0 changed for 1, 2, ... for each iteration.
Consequently, the code provided to search the UIComponent from ViewRoot does not work properly. All forms fields have the same "id". What surprise me more is : they have the same "clientId" in FacesContext too :
contentForm:revisionDocuments:revisionSequenceAdresse
I cannot distinguish, while going through the tree, if I do see the right form field or any of the others.
Does anyone have a hint to solve this ? Or another suggestion to implement the highlight of my fields ? I have to admit, I dont really like my code, I consider dirty to manipulate the viewRoot like I'm doing, but I could not figure out a better solution to have a generic highlight of my fields.
I'm running IceFaces 2.0.2 with JSF-Impl 2.1.1-b04 on JBOss AS 7.0.2.Final.
Thank you in advance for the answers.
Best regards,
Patrick
You should apply this in the client side instead. You've got a collection of client IDs with messages. One of the ways is to pass this information to JavaScript and let it do the job. You can find an example of such a PhaseListener in this article: Set focus and highlight in JSF.
Since JSF 2.0 there is however another way without the need for a PhaseListener. There's a new implicit EL variable, #{component} which refers to the UIComponent instance of the current component. In case of UIInput components, there's an isValid() method. This allows you to do something like:
<h:inputText styleClass="#{component.valid ? '' : 'error'}" />
with this in a CSS file:
.error {
background: #ffe1e1;
}
(yes, you can also do this in a style attribute, but mingling style with markup is a poor practice)
To abstract this away (so that you don't need to repeat it in every input), you can just create a composite component for this, something like <my:input>.
For completeness, here is the solution I finally found to highlight the fields that do have error messages with IceFaces 2.0.2 :
The basic idea is strictly the same than proposed by BalusC on http://balusc.blogspot.com/2007/12/set-focus-in-jsf.html
The piece of code I had to change with IceFaces is the small Javascript call :
<script>
setHighlight('${highlight}');
</script>
I could not find any IceFaces component which is re-rendered at each JS call. I found that placing the script into a panelGroup works most of the time. However, there was a case that did not work :
submitting the form with errors do trigger the JS.
then, re-submitting the form with errors on the same field than previous validation do NOT trigger the JS.
then, re-submitting the form with any error field having no more errors do trigger JS.
then, re-submitting the form with any non-errored field having an error do trigger JS.
For some reason, IceFaces do not render the panelGroup that contains the JS when the set of fields having errors is the same between two calls.
I tried to use the Javascript API with code like Ice.onAsynchronousReceive(), using Prototype library to attach an event to the AJAX completion of the commandButton, but had not much success with it. Some of my tests could run (with errors but did the job) and I could observe similar behavior.
Here is the trick I finally used (ugly but working) :
<ice:panelGroup>
<script type="text/javascript">
var useless = '#{testBean.time}';
setHighlight('${highlight}');
</script>
</ice:panelGroup>
The getTime() function simply return the current timestamp. The value is then always different and trigger the JS execution at any AJAX request.
Sadly, IceFaces do not have the RichFaces useful "oncomplete" attribute, which I do regret highly for this case.
Ugly solution, but funny and working.

MVC Dropdown lists bound depending on the value of another dropdown list

I am trying to write an MVC webpage that has two drop down lists. The content of the second list depends on what is selected in the first.
There does not seem to be a definitive way of doing this using built in MVC functions so I am going to have to roll my own. However I am not clear on the best way of getting all the functionality I require... which is "be the same as webforms" :)
I have created the dropdowns in a way similar to this
However I am not sure how to develop this so that if there is a 'selected' element in the first list when it is first bound this will flow through to automatically binding the second list on page load.
Edit:
Just to be clear I have the ability to bind the filtered list to the second dropdown. However if my Model contains a selection for the first dropdown the selection is set correctly but the second dropdown list does not fill.
(do I have to state I am newish to MVC and Javascript is like some alien language to me?)
Edit2:
I have thought about this a bit more.
Clearly I am strongly influenced by my time developing webforms and I don't quite 'get' MVC yet.
I think that really I have some things I should be catching in my model (ie if I already have the info to set the two dropdowns then I should in some way catch that in the controller and build the dropdowns pre set. Rather than trying to build an "ondatabound" type method and have the view call that (which was my initial intent)... Now I need to go and work out how to do that :)
This is one of the better implementations that I found. The question has also been discussed here.
You task contains 3 subtasks:
You should ajax get list of items for second ddl on changing selection of first ddl by using selected value
You should process action of getting list of items for 2-nd ddl by your Controller and return View with defined content of second ddl
You should update content of second ddl by getting result of processed action
<script type="text/javascript">
$(function(){
$("form #ddl_1").change(function(){
$.get({ // get request
url: "#Url.Action("MyController", "GetList"})" + "/" + $(this).val,
success: function(data){ // updating
$("form #ddl_2").html(data);
}
})
});
</script>
"GetList" action should take parameter "id" if you use default routes table (or you need to create special record at routes table with custom) and return partial view (without master page) with list of options for your ddl2, like this:
<option value="1">First</option>
<option selected value="2">Second</option>
<option value="3">Third</option>
See this blog post for creating cascading dropdown lists in asp.net mvc with downloadable source code.

Update a DropDrownList in a ASP.NET MVC when a user select un option in another DropDrownList

Anyone known how to polulate a combo with values that depends on the user seleccion, I have to combo, Country and Region, When the user select contry I need to go to the database and get the region of the country, Anyone knwows how to do this, if posibile using AJAX.
Thanks.
Do you need to use a particular Ajax libarary?
The Ajax.Net Control Toolkit has the Cascading Dropdown control pre-built for this functionality.
Missed the MVC part, in which case the Ajax Control Toolkit won't work. jQuery is probably the best option, since it makes Ajax extremely easy to code and MS is officially supporting it in conjunction with the MVC framework.
If you created a RESTful service on your site (there should be plenty of documentation on how to do this) you can return a json response through jQuery like this:
The markup:
<select id="opt1">
<option value='1'>Option 1</option>
<option value='2'>Option 2</option>
</select>
<select id="opt2" disabled></select>
Assuming the service will accept 'id' as a parameter and return a json object using this schema for example:
[
{ name: 'option1', value: '1'},
{ name: 'option2', value: '2'}
]
You'd add this javascript to the page:
$(function() {
$('select#opt1').change(function(){
$.getJSON('/data/myservice',{id: this.value},
function(response) {
var options = '';
for (var i = 0; i < response.length; i++) {
options += "<option value='" + response[i].value + "'>"
+ response[i].name + "</option>";
}
$('select#opt2').removeAttr('disabled').html(options);
});
});
});
A quick explanation of what's going on there; jQuery code can be a bit like peeling an onion, so I'll take it a level at a time:
$(function(){}) is shorthand for $(document).ready(function(){}), so it runs the function when the ready event fires.
$('select#opt1').change(function(){}) finds the <select> named 'opt1' and runs the function when the change event fires.
$.getJSON() does the Ajax call for you. JSON responses are returned as strings, and have to be parsed into JSON objects, which $.getJSON does for you automatically. The first field is the url of the service, the second is a name/value pair that is converted to a querystring, and the third is the callback function to handle the response.
I would recommend using jQuery and MVC's JsonResult to achieve this functionality. Have something in your Model to grab the new info from the db based on the given user input. The JsonResult will return this back to the view and you'll use jQuery will populate the drop down accordingly.
A very basic example using jQuery and the MVC framework's JsonResult is available here
I also would recommend jQuery, Json actions are useful if you go and get the data asynchronously. The final result will be a chained combo box setup, there are lots of examples on how to do this in jQuery, this one is fairly good with a live demo and the code. Hopefully it would help you.

Resources