selecting s:select value using javascript - javascript

I have an iterator in jsp and the iterator contains 2 lists:
<s:iterator value="reportNamesList">
<s:select name="hour" listKey="codeDesc" listValue="code" list="hourList" />
<s:select name="minute" listKey="codeDesc" listValue="code" list="minutesList" />
</s:iterator>
Now my requirement is that when hour value is selected (say as 10), the minute dropdown value should also become 10.
I am using javascript. Kindly suggest how to do it.

#Naved is correct; you interact with tag-produced DOM elements the same way as any other (although I'd use jQuery and save yourself a lot of time). You can explicitly set an id by using the id element.
In your case, since you'll have multiple groups of select boxes, you'll need to create the id based on something unique in the reportNamesList, perhaps an id. Your id attribute, then, would probably look something like id="hours_%{id} or if you use the <s:iterator>'s var attribute, id=hours_%{#foo.id}.
Your JavaScript would need to bind each hours select to its associated minutes select.

The code seems that you are coding it in Struts2. Although I am not very much aware of it but the simplest way I found to write any javascript for these types of framework is
Run your code in browser and view the page source
Locate the id or name given to your desired control (in your case it is select for hour). Say it selHour.
Write the javascript code using getElementById('selHour') or getElementsByName('selHour') and do your stuff.
I hope this will help you to give the proper output.

Related

How can I manipulate HTML elements which are added during the runtime?

The code im working on first makes a call to the database. Through this call, it is determined wether there are available workstations in the office or not.
If there are available workstations, "option" elements are added to a "select" element. This is achieved via jquery:
$('#idofselectelement').html(data)
Where "data" represents the markup to be inserted into the "select" element.
Now, my problem is that I'm trying to implement some code which checks wether your "favorite workstation" is available in the selected timeframe and then automatically preselects the respective workstation from the dropdownmenu in the "select" element. Everything is working so far, except for the selection of the workstation from the dropdown menu :/
The part of
I'm rather new to programming with javascript and the HTML DOM, so I'm not sure whether the fact that the options im trying to chose from are added during the runtime?
The code I've tried to manipulate the dropdown menu with is like this:
$('#idofselectelement').val(favoriteworkstation);
However, as I said, this doesn't work.
I've also already tried to output (console.log) the select element's length property right after the code which adds the markup with the available options has run.
But according to the output Im getting, the length is zero Oo
However, the dropdownmenu is definitely being created AND I can indeed manipulate it, but unfortunately not in the way I want to.
If I add an onclick event which sets the value of the respective select element, then the value in the select field indeed changes to the value specified in the event handler.
So I wonder why I can't have the favorite workstation preselected after the timeframe was chosen...
EDIT:
For further insight into the problem, I'm adding a bit more code here.
This is what the HTML Select element looks like BEFORE anything is added during the runtime:
<label for="#sitz">Sitz Nr.</label>
<select type="text" class="form-control" id="sitz" name="sitz" value="">
the markup which is added during the runtime
<option>workstationvalue</option>
<option>workstationvalue</option>
//and so on, depending on the situation...
This is a timing issue.
The js trying to find the element is faster than the actual add of the element to DOM.
Can you describe what you want to do? You might be able to do that before adding the element to DOM.
Editing before adding to DOM is possible if you convert your String to an jQuery object
var $jqueryObject = $(data);
$jqueryObject.find('.classYouSearch').val(value);
$('.whereToAd').html($jqueryObject);

Thymeleaf+spring+Jquery dynamically added forms

Having troubles getting values from dynamically added dropdown in thymeleaf.
This is my first
<select th:field="${offer.offerItemList[__${iterationStatus.index}__].mapa}" class="form-control input-sm ofa">
<option value="0" >---Choose option---</option>
<option th:each="attribute : ${offer.offerProductAttribute}" th:value="${attribute.id}" th:text="${attribute.name}"></option>
</select>
Based on selecton from this dropdown i am generating another dropdown with code similar to this :
var options = '<select th:field="offer.list" class="form-control input-sm"> <option th:value="0">--Choose--</option>';
$.each(value.offerProductAttributeValuesList, function (index, value) {
options += '<option th:value="' + value.id + '">' + value.value+ '</option>';
});
options+= '</select>';
of.closest('tr').find('td:last').html(options);
Dom elements generate fine. Everything is ok but values are never submitted with the rest of input fields.
I have done this many times but with previously rendered
<select>
dropdown on the server side, and i would just appendTo() options, but in this case i cannot do that since i potentially have more than 20 dropdowns, based on clients selection from previous dropdown.
I hope i am being clear enough about my issue.
I am gonna answer my own question, since it took me quite some time to get around this problem, and my solution will probably help someone in the future.
The problem was : i had list of objects, and each one of those objects had another list of objects.
The problem is much easier to solve if you just render entire view from the backend (i was using thymeleaf). That way you can use thymeleaf expressions to map everything correctly
Like this :
First you gonna need for each to iterate over top level list
<tr th:each="item,iterationStatus : ${offer.offerItemList}">
You need to use iterationStatus to iterate over nested List, like this :
<select th:field="${offer.offerItemList[__${iterationStatus.index}__].mapa}">
This little piece of code __${iterationStatus.index}__ will basically use iteration index and you will end up with number for each iteration and rendered view will look like this offer.offerItemList[0].mapa, and 1 and 2 and so on.
this way values will be mapped correctly, BUT, if you want to add fields dynamically things get a bit more complicated.
There is jquery issue. Since jquery pretty much binds selectors when page is rendering, even if you write add another element, say <div class="temp">
and write perfectly good jquery function something like this $('.temp').on('click',function(){ console.log("clicked")});
nothing will happen since jquery didnt bind your newly created element to any select/event listener. The solution is to use (document).
$(document).on("click",".temp",function(){console.log('clicked');})
ok we have fixed front end issue, now newly created items work, but how do i tell spring to bind them to each object within list, which is part of another list? well you will have to use iteration index again :
When rendering the view you will need to save iteration index value in each element(using hidden fields)
Get value for each input field to jquery var like this : var iteration = $(this).closest('tbody').find('td:first-child').find('input').attr('value'); ofc this is path to where i have placed hidden input field, you will have to tell jquery where to look according to your structure.
You will simulate array and index numbers like this
var options = '<select name="offerItemList['+iteration+'].mapaValues">';
And the very last thing you need to be careful about is this : Say you have Object which you would normally send from controller like this model.addAttribute("offer",offer); object Offer has attribute, list of Products, so you would access that list with simple offer.productsList, but each product has list of AttributeValues. So final setup looks like this
offer.products[0].attributes[0].name products is an arrayList of objects of class Product, attributes is an arrayList of objects of class AttributeValues and name is a String. In order to let spring create object of class AttributeValues with information spring is receiving from dynamically(and non-dinamically) created forms from the frond-end, you will need to teach him how. If your new form with has input type="text" you are sending back String, so you will need to create a Custom constructor for
your class AttributeValues which will receive a String and which will tell Spring how to "construct" instance of that class with String.
finally create two constructors, one default and one with String as a value :
public AttributeValues(){}; and another for String public AttributeValues(String n){this.name = n;};
The problem you're most likely seeing here is that you're generating thymeleaf markup on the client-side.
Thymeleaf is a server-side templating language, so the browser (and hence the Javascript) will only ever see plain HTML coming back.
Here's a few approaches to consider:
submit the form each time to get new data in, which means no javascript is required
Output every possible dropdown into your HTML, and show/hide them as needed when the user selects options. Some fairly simple Javascript required, but as you mention - the page size may be pretty big
Add a JSON endpoint to your Spring webapp (see the spring #ResponseBody annotation) that will return just the data you need, then pull that JSON data in when the user selects a dropdown using something like jQuery.get()

Changing the source of struts select tag dynamically using javascript/Jquery

In my code I have a Struts2 select tag(<s:select>). It reads something like this :
<s:select id="s" list="list" listKey="id" listValue="displayValue">
On some selection made by the user, I want to change the value of list attibute to point to some other list.(possibly using javascript/jquery)
What have you tried ? *
You have at least two ways to do this:
1) Perform an AJAX operation to get the new data (in JSON for example, like a List of 'id' and 'description');
then alter the HTML with Javascript, removing the old Options from the Select,
building and adding the new Options to the Select,
and eventually changing some Select attributes;
2) Perform an AJAX operation to get a completely new Select, elaborated server side, returned as a HTML snippet (a JSP with only one <s:select> inside);
then replace it to the original one on the page, for example using its container (like a div) as target of the AJAX operation.
* #AshishGupta suggested me to remove the "What have you tried ?" part to keep the tone positive. Please read the article, it is a must to understand why this should be always the first (positive and legit) question to askers who doesn't post code (for their own good in first place).
Hope that helps, as the rest of my answer.

passing hidden field values to javascript function

is it possible to get the value of the hidden field that is defined in the gridview to the javascript function so I have a gridview that has a linked button defined in it. If the user clicks on the link button, I am invoking a javascript function. I want the hidden field values in the javascript function.
also, I was wondering if it is possible to pass multiple values in one hiden field and then split them later in the javascript function.
any help will be appreciated. I don't want to go to code behind and then invoke the javascript function from there.
The first task is to determine a "suitable selector" for the hidden fields - this can be the ID (get via control.ClientID) of each individual hidden field or a more general selector like "all hidden fields in a particular div (with a particular ID)". Use <%= .. %> (or <%# .. %> in a data-binding context) to put this information into the actual HTML response.
The exact approach will vary - basically, whichever is easiest - for the task.
Then, using your favorite library or advanced browser with applicable selector support (it is easier to find good libraries)1, use the given selector. In jQuery, this might be similar to the following, where fn is the function to process all the values. The actual selector is the stuff in quotes:
fn(jQuery("#clientIdOfGridView input[type='hidden']"))
Which might be written in ASP.NET, which is how the appropriate element ID is injected:
fn(jQuery("#<%= gridView.ClientID %> input[type='hidden']"))
These will both pass a jQuery object representing the hidden field elements to the function. Then use val() and/or each() (see the jQuery documentation and other SO questions) for usage.
There are many questions relating to just jQuery and "selecting values", so this is entire "answer" is really to provide a lead on how to get started - Happy coding :)
1 While this can be done manually with "old-school" finding a element by ID and DOM traversal, I find it a waste of my time to do such a task manually. I like jQuery but there are alternatives. Use the existing wheels; they roll relatively fast.
you can specify as much values in one value-attribute of a hidden field as you like. You must make sure use a delimiter like "," or "#" which you can use in your function to split the string of values according to your needs.

Is there a way to merge get parameters? - HTML/Javascript

often I find myself suprized about simple things, I'm not sure but I believe that this might be one of them.
Often I find myself needing to merge get attributes, especially within filters and search pages within sites. This come be at times quite complicated, as you might want to remove and add parameters dynamically.
Simple way to do it is to use a form, but this get complicated, when adding elements that don't belong within a form. e.g. pagination
For example I might have a URL such as the following
http://www.example.org/ninja_search/?speed__gt=5&night_sight=1&page=1
How would I merge such URL with page=2, substituting the 1 with the new value? Is javascript the only option?
?speed__gt=5&night_sight=1&page=1 + page=2 = ?speed__gt=5&night_sight=1&page=2
Thanks :)
The solution is to use [] to explicitly create an array from the parameters, providing your server side language supports it:
?speed__gt=5&night_sight=1&page[]=1&page[]=2
For example, if your server-side language is PHP, $_GET['page'] will now return an array with 1 as the first element and 2 as the second.
You can use this technique in forms too, by applying it to the name attribute:
<form id="myform">
<input type="hidden" name="page[]" value="1" />
<input type="hidden" name="page[]" value="2" />
</form>
If you're talking about adding a second parameter and ignoring the first, this will happen anyway - the second provided parameter will override the first. Assuming
?speed__gt=5&night_sight=1&page=1&page=2
The value of page at the server will be 2, because the last value given takes priority.

Categories

Resources