Getting multiple selected options with javascript from collection_select, RoR - javascript

I have a view in my Ruby on Rails application where there are two collect_selects on the right side, one of which is a list of users and the other a list of objects which has :multiple => true. When the user has selected a user and at least one object I want to display a chart on the right side with the user and whichever objects have been selected (likely using the gem Flot). I have seen how to get the selected object using selected_index, but I'm stumped as to how you can get an array of all of the selected objects when multiple selections are allowed. I was hoping to do everything in the javascript without having a submit button or anything, but is this possible?

I finally found my own answer. To get all of the selected objects in javascript, for example in a collection_select with id "user_id" you just need to use:
$("#user_id option:selected").each(function() {
// Do whatever with $(this).text() or $(this).val() for each option.
});

Related

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()

Updating gridview's drop down lists using JavaScript?

I have a gridview with several fields. Fields in question are PreviousPoints, GainedPoints, TotalPoints. In the edit mode PreviousPoints is not editable, just data bind, GainedPoints is a drop down list and Total Points is a Drop Down List.
When GainedPoints drop down list selected value changes, I need the TotalPoint selected value to be set to the value of PreviousPoints control + GainedPoints selected value.
But, I cannot refresh the whole page using post back.
How can it be done using JavaScript or something similar without reloading the page?
you can use the onselect() function in javascript and have your computations there.

Add items to dropdownlist with javascript and persist in postback

I'm pretty new to web development, and I've encountered the following problem I don't really understand. Working in VS2010 with visual basic.
I have a page (aspx), which has a gridview, and this has a few columns, including a column with tickboxes and a column 'action', which has an empty, hidden dropdownlist to begin with (every row has this).
Whenever a user ticks a box, I retrieve some values from the server with an AJAX-call (which is my first attempt at AJAX :-)) and with those values I populate a dropdownlist in the 'action' colum of the selected row. So far so good.
The user can then make a selection on the dropdownlist, en then he presses a button (upload), and a postback is done to process the information.
However, in the code behind, I can't retrieve the added items in the dropdownlist (let alone the selected value). I CAN retrieve the dropdownlist, but it has no items.
After googling for some time I realised that client-side changes are not persisted when the form is posted to the server, which I understand- but it also seems odd. The dropdown is created when the page is created, so why doesn't it store the javascipt-added items? Especially since a few work-arounds I found use a hiddenfield to store the added items or selectedvalue. If I can store them in a hiddenfield, why can't I store them in the actual dropdownlist?
I'm obviously not understanding how websites work... But this means that, after a page is initially loaded, you can change values in dropdowns and listboxes and such, but these will never be available serverside?
Edit: some code; the first a javascript-snippet how I add the different values I retrieved through the AJAX call:
var drop = row.findElement("ddlAction"); //find the dropdownelement in the DOM
for (j = 0; j < dropdownitems.length; j++) { //add all the options from xml
option = document.createElement("option");
option.text = dropdownitems[i].getAttribute("text");
option.value = dropdownitems[i].getAttribute("value");
drop.add(option, null);
}
This works fine, the dropdownlist is filled and I can select. But when the page gets posted I do the following in the server code:
Dim SelCount As Integer = LocalFilesGrid.SelectedItems.Count
If SelCount >= 0 Then
For Each dataItem In LocalFilesGrid.SelectedItems
Dim drop As DropDownList
drop = dataItem.FindControl("ddlAction")
If drop.Items.Count = 0 Then 'always zero
MsgBox("Nope")
End If
Next
End If
I'd like to be able to loop through the selected rows of the grid, get the corresponding dropdownlist and selectedvalue.
When you mix such different technologies you will end up in troubles like this. What you are trying to do is bit of Ajax and a bit of ASP.NET. Choose one and then use it. If you choose ASP.NET instead of AJAX call use UpdatePanel which will simplify your life.
If you want to Ajax stuff your self, then handle the button click and submit the request by ajax rather than postback.
The reason why you are able to retrieve the drop down but not the items because you must have declared the drop down in aspx but the items were added on client side, so server has no knowledge about the items.
The reason is ASP.NET uses view state and you can not mess with view state. So you can add the data to hidden field and read them at server but you can not write the data in view state.
The best way is use ASP.NET with UpdatePanels. If you mix, then you will have to keep doing some sort of trick at every step. If you want to do your own Ajax stuff better use MVC and Razor(not mvc with aspx) because it is made for such use.

Binding dynamic select list with asp.net MVC

I have a ViewModel of a form (Name, Address) etc and it's all bound to controls on my page (using Spark engine) - e.g.
!{ Html.DropDownList() }
That works fine. However, there is one DropDownList which is bound that has no values in it to begin with, the values are populated using Ajax (by selecting previous drop downs)
The problem lies when I submit the page and there's a validation error. The page loads and my select list has no values in it (as it hasn't been triggered to get them).
How can I set it up so that the ViewModel knows about values got dynamically so that it can populate the select list on page load?
You'll either need to:
Do this server side by using the Html.DropDownList() call that allows you to pass values in:
Html.DropDownList(string name, IEnumerable<SelectListItem> selectList, string optionLabel, object htmlAttributes)
Or the other way would be to just trigger the same ajax call when the page loads so you don't have duplicated logic.
I'd actually recommend the second way, as it'll keep you from doing the same thing multiple ways, but it does mean that there'
You can add a property of selectlist type in your viewmodel, populate it in constructor, and call it through Html.DropDownList function in your view page. Further since this selectlist is dependent on another list(i.e another property of you viewmodel). in your constructor you can write code like,
say if first listbox is connected to list1 property of type int and allowed values are >0
<code>
if (list1!=0)
{
write code to populate second list based on your first list parameter and also set
the selected value as if selected by the user at submit its stored in the other
property linked to the second list box.
}
</code>
if you are still not clear, write here the concerned code of your viewmodel, and server side database call of your second list, I may help you by editing your code.

Best way to filter a list-view in asp.net MVC

I have a list of data coming from the database and displaying in a table, that works exactly how I want.
What I would like to do, is add a DropDownList to the page that "filters" the data in the table, based on the value of the selected item in the DropDonwList.
For example, the DropDown has these values
Assigned To Me
Assigned To Others
and the list of data, has an "assignedTo" field. When the value in the dropdown changes, I would like to update the list of data.
In WebForms, I would use an UpdatePanel and a DropDownList with autoPostBack=True, how can I get the same effect in MVC?
You use JavaScript/jQuery to bind to onchange/onclick event, and there do a postback:
$(function() {
$("#myelement").click(function(){
$("#secondelement").load('<%= Url.Action("Source") %>?selected=' + $(this).val());
});
}
There're jQuery plugins that do similar things, for example http://dev.chayachronicles.com/jquery/cascade/index.html (not the best one, the first I found).
You have a few options. One way is to create a Controller method that manages the process of grabbing your data (say as a IList), and then uses the Json(...) method of the Controller to serialize it and send it back as JsonResult (here's an example: http://weblogs.asp.net/mehfuzh/archive/2009/04/28/using-of-json-result-in-asp-net-mvc-1-0.aspx).
On your front end, you can wire up some javascript on the dropdown list that uses jQuery to make a $.get (http://api.jquery.com/jQuery.get/) passing back an id of sorts to determine your filter criteria.
Then you use the callback function of the $.get(...) call to manipulate your DOM as you see fit to visually depict the new list of data.

Categories

Resources