Unable to set selected value with easyDropDown.js - javascript

I am attempting to use the easyDropDown.js add on to style my drop boxes but I have encountered an issue. My drop box is not statically created. When the webpage is loaded an array is used to append the drop down list. This drop box appears on multiple pages of my website and I am attempting to set it up so that when the user makes a selection on one page, that selection carries to every page.
Here's a step by step play-through of what the code is doing:
When the page is started it appends the easyDropDown list so that all the values are there.
$('#homeSelectSite').empty();
s = "";
s = "<option value='site'>Site</option>";
for (var i = 0; i < Sites.length; i++) {
s = s + "<option value='" + Sites[i].SiteID + "'>" + Sites[i].SiteID + " " + Sites[i].SiteName + "</option>";
}
$('#homeSelectSite').append(s);
Note: Sites is the array that I am using to fill the drop box.
Now once the drop box list has been created I need to set what value is selected. This value is set in the sessionStorrage if the user has made a selection on another page.
$('#homeSelectSite').easyDropDown();
var selectedSite = sessionStorage.getItem("CurrentSiteID");
if (selectedSite != undefined && selectedSite != null) {
$('#homeSelectSite').val(selectedSite);
}
So what the code is doing is this: emptying the current drop box, appending it with new values, styling it with easyDropDown, and finally setting the selected value. For some reason this will not work. The appending and styleing are working just fine but it will not allow me to set the selected value. I have also tried using this:
$('#homeSelectSite').easyDropDown('select', selectedSite);
Is there a reason why I cannot set the selected value? This all works if I remove everything related to easyDropDown.

I had a similar issue today as I was trying to set the selected value of a dropdown using easyDropDown.
What I did to fix it was to find out the index of the to-be selected option, rather than selecting it by value.
In your case it would be something like:
var index = 0;
$('#homeSelectSite option').each(function(i, item) {
if ($(this).val() === selectedSite) {
index = i;
}
});
$('#homeSelectSite').easyDropDown('select', index);
Hope it helps.

it looks like there's a bug in easyDropDown 2.1.4
Line 326 should be changed from:
index = self.$select.find('option[value='+index+']').index() - 1;
to:
index = self.$select.find('option[value='+index+']').index();
This will only solve the fact that easyDropDown was selecting the previous item instead of the one you wanted, but I'm not sure this would solve your issue. And yes, you must use the 'select' method from the plugin instead of 'val'.

Related

Trying to get values from self submit form using javascript

I have a database from which I generate options for the user to select from. Based on this selection, I submit these values to the same page and get the selections using javascript.
In the same form, I have a radio buttons and a multiple selection menu.
The html is generated as such:
Radio button and multiple option selection code:
htmlstr+="<select multiple>";
for (i=0; i<g.length;i++) {
htmlstr+="<option name='ges[]' value='" + g[i] + "'>" + g[i] + "</option>";
}
htmlstr+="</select><br>";
for (i=0; i<st.length;i++) {
htmlstr+="<input type='radio' name='sts' value='" + st[i] + "'>" + st[i] + "<br>";
}
These are both placed within a form, which then has a submit button.
Upon clicking the submit button, I want to know the values of the selections. I understand the multiple selection will be an array, but how do I get the array of values, and I cannot even get the value of the selected radio button. I have already tried getting the value using the .value attribute attached to the name, however this does not work.
There is not a real simple way of doing it. You'll have to check each option.
There is a HTMLSelectElement.selectedOptions interface that is documented. But it's not used much and I'm not sure of the browser support. Plus, it only applies to the select control and not the radio controls. You can check it out here though: https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement
But for a more reliable method, try this...
For the select control, iterate through the selectControl.options array, and check each item for a selected attribute. If the selected attribute is true, then add that value to your own array.
Pseudocode:
for (var i in select.options) {
if (select.options[i] && select.options[i].selected) {
selectedOptions.push(select.options[i].value);
}
}
For the radio buttons, iterate through the array of objects in the dom (getElementsByName), and check the checked attribute. It it is true, add that value to your array.
Pseudocode:
for (var i in radios) {
if (radios[i] && radios[i].checked) {
selectedOptions.push(radios[i].value);
}
}
Here is a full working sample using your code:
jsFiddle: https://jsfiddle.net/mspinks/u890j86j/3/

Get Selected value of DropDownListFor based on DropDown ID

I have table in my view in which the first column has the Drop down box for each row. The last column has a button, on click of which I need to get the value from the Drop Down box. I have specified ID to each DropDown box. But I am unable to get the correct selected value. If I use a single Drop Down box, I get desired value
HTML Code:
<td class="col-md-2">
#Html.DropDownListFor(model => model.SelectedBranch, Model.BranchList, new { id = "ddBranch-" + item.ID, style = "display:none;", #Class = "form-control m-right-sm" })
</td>
JS Code:
If I use only one dropdown box, below code works fine:
function update(id) {
var branchid = $("#SelectedBranch").val();
But since I have multiple Dropdown box, I tried using below code:
function update(id) {
var e = document.getElementById("ddBranch-" + id);
var br = e.options[e.selectedIndex].value;
Now the first statement works fine. I get values in var e. I checked and found that the second item has property selected to true. But the second statement gives error. I tried couple of similar approach suggested on SO but nothing seem to be working. I am using asp.net mvc .Please advise.
You are just doing it the hard way, Since you already have dynamic id's to each drop-down you can build the same id by string concatenation. Use this
var branchid = $("#ddBranch-" + id).val();

Submitting hidden field data on Android/iOS browsers does not work

I am working on a site which connects to a MySQL database and lets you display/edit the data in it. The site uses JavaScript and PHP, with HTML and CSS parts (these are added using JS).
The site works, does everything I wanted it to do, but only from PC. When I try to use it from a smartphone, some of the hidden fields' value doesn't get submitted correctly to the PHP page responsible to working with them.
First, I have a few of this select box:
var maxLvl;
var select = document.createElement( 'select' );
var trooplist = [archerLvl, giantLvl, wizardLvl, balloonLvl, dragonLvl]; //this array contains numbers, which will be used to set the starting option in the select
select.id = "select" + k + " " + i; //k and i are both variables in their respective for loop: k goes from 0 to 2, in it there's another with i.
select.onblur = function() {
var selectid = this.id;
var last = selectid.slice(-1);
if(last==0){
document.getElementById("hiddenArcherid").value = this.value;
alert(document.getElementById("hiddenArcherid").name + " " + document.getElementById("hiddenArcherid").value);
}else if(last==1){
document.getElementById("hiddenGiant").value = this.value;
alert(document.getElementById("hiddenGiant").name + " " + document.getElementById("hiddenGiant").value);
}else if(last==2){
document.getElementById("hiddenWizard").value = this.value;
alert(document.getElementById("hiddenWizard").name + " " + document.getElementById("hiddenWizard").value);
}else if(last==3){
document.getElementById("hiddenBalloon").value = this.value;
alert(document.getElementById("hiddenBalloon").name + " " + document.getElementById("hiddenBalloon").value);
}else if(last==4){
document.getElementById("hiddenDragon").value = this.value;
alert(document.getElementById("hiddenDragon").name + " " + document.getElementById("hiddenDragon").value);
}
};
select.style.position = "absolute";
select.style.left = 250 + (i*(width + (width/10))) +"px";
select.style.top = 110 + height + (rowcounter * (height * 1.5)) + "px";
select.style.width = width;
if(i==0 || i==1 || i==2 || i==3)
maxLvl = 6;
else
maxLvl=4;
for(var l=0; l <= maxLvl; l++){
var option = document.createElement( 'option' );
option.setAttribute("value", l);
option.innerHTML = "Level " + l;
select.appendChild(option);
}
select.selectedIndex = trooplist[i];
IDarray.push(select.id);
document.body.appendChild(select);
This code runs in a for loop, and creates 5 select boxes using data passed by a function. Then, when the user selects a new option, the option's value is stored in a HTML hidden input field with. Like this one:
var hiddenArcher = document.createElement('input');
hiddenArcher.setAttribute("type","hidden");
hiddenArcher.name = "hiddenArcher";
hiddenArcher.id = "hiddenArcherid";
hiddenArcher.setAttribute("value", document.getElementById("select1 0").value);
formNew.appendChild(hiddenArcher);
These input fields have a basic value, which is the default of the select box - 0 if the user creates a new entry, or an already known value if the user wants to modify an already existing entry. All the input fields have the same structure, only the JS var, the name, the id and the default value changes.
The input fields are part of the formNew form, which has multiple submit buttons - pressing those buttons posts the fields' values to a PHP page, which executes the MySQL queries, depending on which button was pressed. For this, I use if/else if (isset). Then the PHP redirects (by using header("Location: http://my_sites_address"); exit();) to the main page - the one I where the select boxes are.
If I try it from Chrome, the site works - The right values get passed, the PHP executes the right queries correctly. I can add new entry, and both delete or modify existing ones. When I try it on Android (via emulator) or iOS (via my friend's phone), although I can select the values I want to change, and the alerts display the correct data, too, when I hit submit, nothing happens within the database, it seems like I did nothing. The browser gets redirected to the PHP, so I guess the submit does happen, but there will be no changes in the database. The PHP simply redirects to the main page, and that's all.
The only function can be used successfully on phone is deleting the entry, most likely because the hidden field responsible for storing the row's ID gets it's value the moment it's added to (a different) form, and the value never changes, only when the user switches to a different entry.
The hidden fields "physically" (based on their location in the file) are declared later than the select boxes.
Currently, the code acts this way on phone:
1) I start editing the entry. The select boxes show up.
2) I can select the desired value.
3) An alert pops up, confirming the value got passed to the hidden field.
4) I press the submit button, comes the PHP, then the redirects, and I am back where I started. There are no changes in the database.
I already tried to switch onchange to onblur at the select boxes; I made sure JS is enabled (which was totally unnecessary, because the images/texts displayed with JS). Right now I have no idea what's wrong.
Are any of you experienced something similar, or has any idea what should I do?
Some browsers fail to correctly and completely recognize the programmatic change of a hidden input's value immediately after it is changed. If you submit the form directly after changing the hidden input's value via javascript, the value sent for that input will be the pre-change value, rather than the value you set in javascript.
Unfortunately, I don't have a list of browsers that exhibit this behavior, nor do I know the exact mechanics behind it. What I do know is that I've run into the issue you're describing, and I have always been able to solve it by triggering a change event on the hidden input after changing its value via javascript.
For those using plain javascript with no external libraries, your code would look something like this (see here):
<input id="myHidden" name="myHidden" type="hidden" value="old value"/>
<script type="text/javascript">
var hiddenInput = document.getElementById('myHidden');
hiddenInput.value = 'new value';
console.log(hiddenInput.value); // = 'new value'
// Submit the form now, and myHidden='old value' will be sent to the server
// Set up and trigger the change event on our input:
var changeEvent = document.createEvent("UIEvents");
changeEvent.initUIEvent("change", true, true);
hiddenInput.dispatchEvent(changeEvent);
// Submit the form now, and myHidden='new value' will be sent to the server
</script>
For those using jQuery or a similar library, the code is a little more concise:
<input id="myHidden" name="myHidden" value="old value"/>
<script type="text/javascript">
var $hiddenInput = $('#myHidden');
$hiddenInput.val('new value');
console.log($hiddenInput.val()); // = 'new value'
// Submit the form now, and myHidden='old value' will be sent to the server
// Trigger the change event on our input:
$hiddenInput.change();
// Submit the form now, and myHidden='new value' will be sent to the server
</script>
Really concise example (one-liner) using jQuery:
<input id="myHidden" name="myHidden" value="old value"/>
<script type="text/javascript">
$('#myHidden').val('new value').change();
// Submit the form now, and myHidden='new value' will be sent to the server
</script>
Here's a working example using a slightly simplified version of the code supplied in the original question.
In our case, the issue was simply that we had this check in PHP:
if (isset($POST['myvalue']) && !empty($POST['myvalue'])) {
// save
}
However, in PHP 0 is considered empty in PHP and thats exactly what the passed value was!

Select attribute not changed after change of select element

I have a table in which a few columns contains select elements. In the tfoot I have one input element for each row used for filtering the row based on the selected value in the select element.
When loading the table and directly filtering the columns with selects, than it works and the table is filtered.
But when making a change in the select elements, the filter function is not taking any notice that the value has changed.
Checking out the html I can see that the "selected" attribute is still on the option that was selected when loading. Hence, it doesn't get updated when making an actual changed (identified in both FF and Chrome).
But from jQuery, searching for the selected value (.find(":selected")) works. So I figure that I can use that to find the value and then set the selected attribute to whatever was selected. This is how I am trying to do it:
$("select[id^='qu_owner']").live('change', function (e) {
var owner = $(this).val();
console.log(owner);
var ticketid = $(this).attr('id').substr(9);
$($(this) + " option[value=" + owner + "]").attr("selected", "selected"); //Update: this has been removed
});
But the selected attribute is still not updated in the element.
Any clue how to do this? I need the filtering to work and it's looking at the selected attibute. Is it not possible to make this kind of update to the select element?
UPDATE
Ok, based on the comments and answers below I understand there are better ways of doing what I did above. So instead of using $(this).find(":selected").val(); I now use $(this).val();. Also, I did remove the last row since I understand one shouldn't try to set the selected attribute.
And also, I now understand that the code where I have the actual problem is the filter function. This is for DataTables so it's a plugin but this is the significant part:
aData[i] is the actual table cell. Hence, it's just text but in this case it's the text for my select element. I think below is heading in the right direction, but still not working (check comments next to console.log-rows):
function( oSettings, aData, iDataIndex ) {
var ret = true;
//Loop through all input fields i tfoot that has class 'sl_filter' attached
$('tfoot .sl_filter').each(function(i, obj){
//$(this) can be used. Get the index of this colum.
var i = $("tfoot input").index($(this));
//Create regexp to math
var r = new RegExp($(this).val(), "i");
//Get the selected option from the column
console.log($(aData[i]).attr('id')); //Properly prints the ID
console.log($(aData[i] + " option:selected").text()); //Prints all options, not only the selected on
console.log($(aData[i] + " option:selected").val()); //Prints the value of the id that was selected when data was loaded, even if a new option has been chosen
console.log($(aData[i]).val()); //Prints the value of the id that was selected when data was loaded, even if a new option has been chosen
var str = $(aData[i] + " option:selected").text();
/*Test to see if there is a match or if the input value is the default
(the initial value of input before it has any fokus/text) */
if(r.test(str) || $(this).val()=="Search"){
//Return true only exits this function
return true;
}else{
/*Return false returns both function an .each. Retain 'false' in a variable scoped
to be reached outside the .each */
ret = false;
return false;
}
});
//Return true or false
return ret;
}
It is the text for the selected element I need to get hold of. That's what should be filtered upon. How can I do that?
Update
To narrow it down, I have created a jsfiddle with what's necessary. It's all about how to extract the text from the selected option: jsfiddle
aData[i] = the table cell. In jsfiddle, i use "sel" as variable for the content of the cell. The text for sel is copied form aData[i].
There's no need to change the attribute of the <option> - that's supposed to contain the original state of the element as it was downloaded from the server.
Your filter should be checking the selected property of the chosen option, e.g.:
.filter(function() {
return this.selected; // check the boolean property
})
This is also how the :selected pseudo-selector works - it checks the current value of the property, not the attribute.
Note that in the change handler for a <select> element, you can just use this.value to get the currently selected value.
$('select').on('change', function() {
// current value
var value = this.value;
// text of the currently selected option.
var text = this.options[this.selectedIndex].text;
}

performing jQuery show/hide on dynamically created content

I have a page I created with jQuery, and in this page is a table where the table rows have classnames that identify them as a certain color (i.e. tr class="yellowclass").
The user is able to filter rows by clicking a checkbox that will show/hide tables of a certain color.
My problem is that the table is generated on the fly via getJSON requests. to add the new content to the table, I first do a children().remove() on the table's tbody, ($('#my_table_tbody').children().remove()), and then I use appendTo to add the new table information back in.
an example of this function is:
$('#my_table_tbody').children().remove();
$.getJSON("http://my_url.com/my_cgi_bin/my_cgi", {data: mydata}, function(j) {
var mylength = j.length;
for (var k = mylength - 1; k >= 0; k--)
$('<tr class="' + j[k].color + '"><td class="my_first_col_class">' + j[k].data1 + '</td><td class="my_second_col_class">' + j[k].data2 + '</td></tr>').appendTo($('#my_table_tbody'));
});
Now at the end of this function, I am trying to check to see if checkboxes are checked, and if so, to show/hide the new information. For example, to basically call
if (('#my_yellow_color_cb').attr('checked'))
$('.yellowclass').show();
else
$('.yellowclass').hide();
The problem is, the page isn't wanting to "remember" what has been checked. In other words, if the 'yellowclass' check box is unchecked, and the page reloads with new table data, the yellowclass class is still showing up, when it really should be hidden.
i suspect this has something to do with the DOM, and creating proper DOM elements that can be shown/hidden. But i don't know how to do this in my particular situation. I am a systems programmer, and am just doing this to program a tool that would provide our testers with some status info. i am no expert when it comes to JavaScript and have little understanding of the DOM, and can't seem to figure this one out.
How can I insert into the page so that I can properly show and hide this information?
If I update the page with new table data, and then check and uncheck boxes, then things work fine. But if I load table data, and just check the status of the boxes as they are, it's not wanting to work. Does jQuery take a little time to get DOM objects created before they can be accessed?
Thanks for any help.
Perhaps something like this?
$('#my_table_tbody').children().remove();
$.getJSON("http://my_url.com/my_cgi_bin/my_cgi", {data: mydata}, function(j) {
var mylength = j.length;
for (var k = mylength - 1; k >= 0; k--) {
var $row = $('<tr class="' + j[k].color + '"><td class="my_first_col_class">' + j[k].data1 + '</td><td class="my_second_col_class">' + j[k].data2 + '</td></tr>');
if ($('#my_yellow_color_cb:checked').length == 0 && $row.is('.yellow'))
$row.hide();
$row.appendTo('#my_table_tbody');
}
});
Basically, each row is created as a DOM fragment and then the conditional is run. If $('#my_yellow_color_cb:checked').length is 0, meaning the yellow color check box is not checked, then .hide() is executed for the row. Then, the row is added to the end of the tbody. You'll want to extend the if statement with more logic for your other colors.

Categories

Resources