I have an HTML code with a select tag where the options are dynamically populated. Once the onchange event occurs the option selected gets disabled. And also if any page navigation happens the options populated previously are retrieved.
In my case once options are populated and any option is selected gets disabled( intention to not allow the user to select it again). So there might be a case where out of 3 options only two are selected and disabled so once I refresh and the options not selected previously should be enabled. And the options selected previously should be disabled. But my code enables all the options after refresh. How can I fix this?
html code
<select id="convoy_list" id="list" onchange="fnSelected(this)">
<option>Values</option>
</select>
js code
//This function says what happnes on option change
function fnSelected(selctdOption){
var vehId=selctdOption.options[selctdOption.selectedIndex].disabled=true;
localStorage.setItem("vehId",vehId);
//some code and further process
}
//this function says the process on the drop-down list --on how data is populated
function test(){
$.ajax({
//some requests and data sent
//get the response back
success:function(responsedata){
for(i=0;i<responsedata.data;i++):
{
var unitID=//some value from the ajax response
if(somecondition)
{
var select=$(#convoy_list);
$('<option>').text(unitID).appendTo(select);
var conArr=[];
conArr=unitID;
test=JSON.stringify(conArr);
localStorage.setItem("test"+i,test);
}
}
}
});
}
//In the display function--on refresh how the stored are retrievd.
function display(){
for(var i=0;i<localStorage.length;i++){
var listId=$.parseJSON(localStorage.getItem("test"+i)));
var select=$(#list);
$('<option>').text(listId).appendTo(select);
}
}
In the display function the previously populated values for the drop down are retrieved but the options which were selected are not disabled. Instead all the options are enabled.
I tried the following in display function
if(localStorage.getItem("vehId")==true){
var select=$(#list);
$('<option>').text(listId).attr("disabled",true).appendTo(select);
}
But this does not work.
Elements on your page shouldn't have same ids
<select id="convoy_list" onchange="fnSelected(this)">
<option>Values</option>
</select>
In your fnSelected() function you always store item {"vehId" : true} no matter what item is selected. Instead, you should for example first assign some Id to each <option\> and then save the state only for them.
For example:
function test(){
$.ajax({
//some requests and data sent
//get the response back
success:function(responsedata){
for(i=0;i<responsedata.data;i++):
{
var unitID=//some value from the ajax response
if(somecondition)
{
var select=$("#convoy_list"); \\don't forget quotes with selectors.
var itemId = "test" + i;
$('<option>').text(unitID).attr("id", itemId) \\we have set id for option
.appendTo(select);
var conArr=[];
conArr=unitID;
test=JSON.stringify(conArr);
localStorage.setItem(itemId,test);
}
}
}
});
}
Now we can use that id in fnSelected():
function fnSelected(options) {
var selected = $(options).children(":selected");
selected.prop("disabled","disabled");
localStorage.setItem(selected.attr("id") + "disabled", true);
}
And now in display():
function display(){
for(var i=0;i<localStorage.length;i++){
var listId = $.parseJSON(localStorage.getItem("test"+i)));
var select = $("convoy_list");
var option = $('<option>').text(listId).id(listId);
.appendTo(select);
if(localStorage.getItem(listId + "disabled") == "true"){
option.prop("disabled","disabled");
}
option.appendTo(select);
}
}
Also maybe not intended you used following shortcut in your fnSelected:
var a = b = val;
which is the same as b = val; var a = b;
So your fnSelected() function was equivalent to
function fnSelected(selctdOption){
selctdOption.options[selctdOption.selectedIndex].disabled=true;
var vehId = selctdOption.options[selctdOption.selectedIndex].disabled;
localStorage.setItem("vehId",vehId); \\ and "vehId" is just a string, always the same.
}
Beware of some errors, I didn't test all of this, but hope logic is understood.
Related
I am developing a dynamically generated and self updating form in ASP.NET MVC using javavascript, Jquery, JSON/Ajax calls.
Here is how I set up my view code from the controller. I loop through all available controls from the controller:
<ul>
#using (Html.BeginForm("Index", "WebMan", FormMethod.Post)) {
foreach (var row in Model.controls)
{
<li>
<label>#row.Name</label>
#if (row.ControlType == "STRING" || row.ControlType == COMMENT")
{
<input type="text" name="#row.Name" id="#row.NameID" value="#row.Value" data-original-value="#row.Value" class="form-control data-field" style="width: 300px"/>
}
else if (row.ControlType == "DDL")
{
<select name="#row.Name" id="#row.NameID" class="form-control data-field" value="#row.Value" data-original-value="#row.Value" style="width: 300px">
#foreach (var o in row.Options)
{
<option value="#o.Value">#o.Text</option>
}
</select>
}
</li>
}
<button type="submit">Update</button>
}
</ul>
(notice that I set the value to the value from the database and I also set the “data-original-value” to the value from the database as well)
I am using the “data-original-value” to check to see if the value has changed later.
I also set up a javascript timer that executes every 5 seconds. This timer is meant to “update” the page. (code for timer below)
var interval = setInterval(function () { Update(); }, 10000);
When the timer executes, we loop through each control in the “data-field” class. This allows me to check each dynamically generated control.
Basically, If a user has edited a control, I DO NOT want to update that control, I want to ignore it. I only want to update that specific control if a user has not changed the value. When a user changes the value, the current value != orig value (Data-original-value), so we set the field to yellow and ignore the database update code.
function Update() {
UpdateControls();
}
function UpdateControls() {
$(".data-field").each(function () {
var nameAttr = $(this).attr('name');
var id = $(this).attr('id');
var val = document.getElementById(id).value;
var origVal = $(this).data("original-value");
if (origVal == val) {
//user did not change control, update from database
var url = "/WebMan/UpdateControlsFromDB/";
$.ajax({
url: url,
data: { name: nameAttr },
cache: false,
type: "POST",
success: function (data) {
if (data != null) {
document.getElementById(id).setAttribute("data-original-value", data);
document.getElementById(id).value = data;
}
else {
alert(data);
}
},
error: function (response) {
alert("Issue updating the page controls from database");
}
});
}
else {
document.getElementById(id).style.backgroundColor = "yellow";
//user changed control, do not update control and change color
}
});
}
If no change, this ajax method in my controller is called:
[HttpPost]
public ActionResult UpdateControlsFromDB(string name)
{
var curValue= db.Setup.Where(x => x.Name == name).Select(x =>Value).FirstOrDefault();
return Json(curValue);
}
The code works correctly if a user modifies the field. It senses that the user modifies the code, and changes the field yellow.
The part that does not work correctly, is if the database updates the field. When the database first updates the field, it looks great. We set the “data-original-field” value to the value as well, to tell our code that is should not turn yellow and the user has not modified it.
But after another update, “value” and “original-value” do not match. The code document.getElementById(id).value somehow gets the OLD version of the control. It does not get the current value. So then on next loop, the values don’t match and we stop updating from DB and the control turns yellow.
My issue is that my code senses that the control value changed (database update) and turns it yellow, when I only want to turn the control yellow when a USER has changed the value in the control.
I only want to change the control and prevent updating from DB when the control has been modified by the user.
Thank you for any help.
I am using Jade to create a drop down list on a webpage. I want to have this webpage constantly reload(perhaps by a certain time interval) when an item is selected, but I want it to reload with the same selection still selected.
Using something like meta(http-equiv='refresh', content='30') could work for me, but it only reloads the original page every 30 seconds, but not the page with the selected item in the list already selected.
Here is my code:
select(id="foo", multiple="2", size=listStuff.length)
each val in listStuff
option(value=val)=val
script.
$('#foo').on('change', function(context) {
//insert what the selection displays when changed
});
I know I am using jade, but any html experience is welcome, as I can convert between the two languages.
So you need to persist the option in select after refresh. You have couple of options, use session/local storage api or set it in a cookie.
using session storage:
$('#foo').on('change', function(context) {
sessionStorage.setItem("foo", $("#foo").val());
});
and then on page load
$('#foo').val(sessionStorage.getItem("foo"));
If on cookie, you would use something like (jQuery cookie)
$.cookie("foo", $("#foo").val());
Following is an example using the Query string from the URL.
I use the id of the select element as the query string name.
window.addEventListener('load', initPage, false);
var elSelect; // select element
function initPage(sender) {
var selectionValue; // selection from url
// get select, set value, refresh page in 30 seconds
elSelect = document.getElementById('foo');
selectionValue = getQueryString(elSelect.id);
if (selectionValue) {
elSelect.value = selectionValue;
}
setTimeout(refreshPage, 30000);
}
function refreshPage(sender) {
var newUrl; // url to load
// set new query portion, reload
newUrl = "?" + elSelect.id + "=" + elSelect.value;
window.location.href = window.location.href.split('?')[0] + newUrl;
}
// get query string value by name
function getQueryString(sParm) {
var asParms; // query String parameters array
var sLocation; // location URL
var sParmName; // parameter name
var sParmVal; // parameter value
// return false if not found
sParmVal = false;
// split query portion of url, look for sParm name
sLocation = location.search.substring(1, location.search.length);
asParms = sLocation.split("&");
for (var i = 0; i < asParms.length; i++) {
sParmName = asParms[i].substring(0,asParms[i].indexOf("="));
if (sParmName === sParm) {
sParmVal = asParms[i].substring(asParms[i].indexOf("=") + 1)
}
}
return sParmVal;
}
<select id="foo">
<option value="1" selected>fe</option>
<option value="2">fi</option>
<option value="3">fo</option>
</select>
I am trying to fill in a select dropdown list with an array of options from a call to our server. I have the server call setup to run and fill a hidden iframe and that part works fine. I need to get the data from the iframe and use that array to fill the option list.
In the main/parent page I have this table cell for the select list:
<tr>
<td><select id="ymm_model" name="vmodel">
<option value="" selected="selected">Select Model</option>
</select></td>
</tr>
This function is in the main/parent in the scripts area and is called by a prior select list onchange, and was my attempt to fill the select list after running the call to fill the iframe. The filling of the iframe works and shows the data.
function getModels(make) // open iframe and do call
{
window.frames['dataframe'].window.location.href='http://www.atkcores.com/cgi-bin /vinholmodel.cgi?myear='+document.vinhol.ymm_year.value+'&mmake='+make;
var select = document.getElementById("ymm_model");
var mods = document.getElementById('dataframe').contentWindow.document.getElementById['models'];
for (var i = 0; i < mods.length; i++) {
var option = document.createElement('option');
option.text = option.value = mods[i];
select.add(option, 1)
}
}
I also tried this function which would run from the page that loads into the iframe from my server script and after the page loaded.
function takedata(passed)
{
var select = document.getElementById("ymm_model");
var mods = document.getElementById('dataframe').contentWindow.document.getElementById['models'];
for (var i = 0; i < mods.length; i++) {
var option = document.createElement('option');
option.text = option.value = mods[i];
select.add(option, 1)
}
}
This is the page that is formed in my server process that fills the iframe.
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="content-type">
</head>
<script>
function init()
{
window.parent.takedata(document.getElementById("moddata").value);
return true;
}
</script>
<body onload="init();">
<form name="vinmodels">
<div id="moddata"> var models =["ACCORD","CIVIC","CR-V","DEL SOL","ODYSSEY","PASSPORT","PRELUDE"]; </div>
</form>
</body>
</html>
The content in the moddata div is what I need to use to fill the select list.
Thanks for any guidance or suggestions you have,
Scott
I think you're making it more complicated than it needs to be. You need to get an array of data from a server, which is what AJAX was all but built for.
Your server should instead of sending an HTML response, send an application/json response with the array. It should look like this:
{
"models": ["ACCORD","CIVIC","CR-V","CR-Z","CROSSTOUR","FIT","INSIGHT","ODYSSEY","PILOT","RIDGELINE"]
}
Remember that a JSON object relies on key-value pairs. We only have one piece of data (the models array), so we've assigned it the key "models".
From here, just pull in the data using your favorite AJAX methodology. I'm using jQuery for this example, but you can also use XHR requests for a non-jQuery approach. I've included a fiddle, but note that the fiddle won't "work" properly since it is not on the atkcores.com domain (this is a Cross-Origin Sharing issue).
You should however be able to understand the gist of it and create your own version.
//This is what your server should respond with a type of 'application/json'
var serverResponse = '{ "models": ["ACCORD","CIVIC","CR-V","CR-Z","CROSSTOUR","FIT","INSIGHT","ODYSSEY","PILOT","RIDGELINE"] }';
//This uses jQuery for a quick demonstration, look up how to do AJAX without jQuery using XHR objects if you don't want to use jQuery
$(document).ready(function() {
$.get('http://www.atkcores.com/cgi-bin/vinholmodel.cgi?myear=2014&mmake=honda')
.success(function(data) {
//This will not work on the demo since your server doesn't support CORS, but
//this is where you would process the data.
handleResponse(data);
}).fail(function(jqXHR, message) {
//In this demonstration, this will always hit because of the above CORS issue
});
//Pretend the above AJAX worked, we handle the response
//Since your server is responding with 'application/json', we don't need to parse
//the string above as we do here
handleResponse(JSON.parse(serverResponse));
});
function handleResponse(data) {
//Server passes the array in a JSON object with the key 'models'
var modelsArray = data.models;
var select = document.getElementById('ymm_model');
for (var i = 0; i < modelsArray.length; i++) {
var option = document.createElement('option');
option.text = option.value = modelsArray[i];
select.add(option, 1);
}
}
http://jsfiddle.net/vg0g7gzL/
I need two drop down form boxes. Selecting content in the first one updates the second one.
However I do not want to use AJAX JSON updating in the Javascript (I've found these online but can't get them working on my server). What I would rather do is generate a list when the page loads and have the Javascript pull from a list already loaded on the page. The data is coming from a mySQL database but since it is preloaded on the page its faster.
I can handle getting the data from the database but what I need is the JS that changes the for the second drop down box getting the data from a variable list or some other function rather then a AJAX JSON update.
I'll use jquery if I can but all I find online is AJAX versions of this script.
<select id="firstselect" onchange="changeMe(id)" />
<script>
function changeMe(id) {
var options1=[1,2,3,4];
var options2=[2,3,4,5];
var options = null;
if (id = 1) {
var options = options1;
} else {
var options = options2;
}
for (var i = 0; i < options.length; i++) {
var optn = document.createElement("OPTION");
optn.text = options[i];
optn.value = options[i];
$('secondSelect').add(option, i);
}
}
</script>
1 naga naga123
2 Tamil tamil123
3 vinod vinod123
4 naveen naveen123
5 jakkir jakkir123
save edit delete
UserID:
UserName:
Password:
I have check box at the end of each row. When I click the check box and select edit the values should get displayed in the text boxes corresponding to userId, userName & Password.
My js code for edit is
function Edit(){
var i=dwr.util.getValue("userId");
LoginManagement.selectId(i,function(login){
dwr.util.setValues({userId:userId, userName:login.userName,
passWord:login.passWord});
});
}
My js code for checkbox is
function Intialize(){
LoginManagement.getLoginDetails(function(loginList){
var x = "";
for(var i=0; i<loginList.length; i++){
var login =loginList[i];
x += "<tr><td>"+login.userId+"</td><td>"+login.userName+"</td><td>"+login.passWord+"</td><td><input type = 'checkbox' id = 'cbid"+login.userId+"'</td></tr>";
}
$("#loginTable").html(x);
});
}
How should i get the id value in edit so that if i click the button it should display the values corresponding. Any suggestion please?
Hope I understand you correctly.
Remove Edit() from onclick of edit link and continue the Initialize function as follows:
...
$("#loginTable").html(x);
ids = ['userId', 'userName', 'Password']; // Ids of text boxes to be populated
$("#editlink").click(function(){ // Assuming edit link has id="editlink"
var tds = $("#loginTable").find("input:checked[type=checkbox]").parent().siblings();
for(var i = 0; i < ids.length; i++){
$('#' + ids[i]).html($(tds[i]).html());
}
Edit(); // Better copy the code of Edit() directly in here
return false; // Prevent default click action (go to href)
});
});
If this is wrong please post the complete HTML as well.
the id can be retrieved by using the attr var idvalue = $("input:last").attr("id"); but you have to get reference to the checkbox in your scenario .. if you have a css class name associated with it use that like $(.classname) and then use the attr to get the value.