one var with multiples "selected" question relates to "employee".
When open the system will show up all question, whatever I pressed the button will show me an employee and I will select one (ex: Brian for the first question) and will select "positive".
When I click on my second question, Brian is already selected. HERE is my problem.
Should be select only in one question and is making flag for all question.
anything wrong with the boolean?
var resultHandler = function(){
currentQuestion = this;
$('#details-name').text(currentQuestion.question);
$('#projectPopUp').show();
};
var cancel = function() {
//do nothing for now
}
var commenthandler = function() {
var value = $("#" + this.id + "-comment").val();
this.comments = value;
$("#" + this.id + "-comment").val(value);
};
var names = [];
// bt select ppl
var nameList = function (){
for (var i = 0; i < employees.length; i++) {
var name = employees[i];
var id = i;
var data = {
id: 'e' +id,
name: name
};
names.push(data);
$('#detailsgrid tbody').append(Utils.processTemplate("#popupPersonTemplate tbody", data));
$("#" + data.id + "-status").text('Select');
$("#" + data.id + "-status").click(statusHandler.bind(data));
}
};
var statusHandler = function(){
var previousResult = this.inspectionResult;
var answerIndex = answers.indexOf(previousResult);
/** -1 is if the answer is not found if not found defaults to first answer
* else it gets the next answer
*/
console.log('Answer Index: ' + answerIndex);
if (answerIndex == -1) {
console.log('Answer index is -1');
answerIndex = 0;
this.active = 'false';
updateActiveStatus(this);
} else {
answerIndex = (answerIndex + 1) % answers.length;
}
var currentResult = answers[answerIndex];
this.inspectionResult = currentResult;
$("#" + this.id + "-status").text(currentResult);
// commentvisibilitymanager(this);
};
var buildQuestionnaire = function(){
parseInitialDataHolder();
for (var i = 0; i < ARRAY_OF_QUESTIONS.length; i++){
var id = ARRAY_OF_QUESTIONS[i].code;
if (id && typeof id != 'undefined'){
id = id.replace('.', '-');
};
var data = {
id: id,
question: ARRAY_OF_QUESTIONS[i].question,
inspectionResult: "", //defaultResults
employee_results: [],
active: true
};
var initialdata = initialdataholder[id];
if(initialdata) {
data = initialdata;
}
dataholder.push(data);
if (typeof ARRAY_OF_QUESTIONS[i].header == 'undefined') {
$('#questionsTable tbody').append(Utils.processTemplate("#rowTemplate tbody", data));
$("#" + id + "-inspectionResult").text(data.inspectionResult || 'Select');
$("#" + id + "-inspectionResult").click(resultHandler.bind(data));
updateActiveStatus(data);
commentvisibilitymanager(data);
}
else {
$('#questionsTable tbody').append(Utils.processTemplate("#sectionRowTemplate tbody", data));
}
}
}
//to close the popup
var closePopup = function() {
$('#projectPopUp').hide();
};
$(document).ready(function() {
buildQuestionnaire();
nameList();
});
Related
The change is not firing on dropdownlist item change in Google Chrome.
The same script is working perfectly in Firefox.
I have used ui.dropdown and I'm trying to bind to the change event.
This is the code from my script Dropdown.js
(function ($, undefined) {
$.widget("ui.Dropdown", {
options: {
defaultLabel: "Select...",
dontDisplay: false
},
_create: function _create() {
var self = this;
var element = self.element;
var options = self.options;
// Element is a select element
element.wrap("<div class='sc-dropdown'></div>");
var parent = options.parent = element.parent();
if (options.dontDisplay) {
parent.addClass("sc-incompleteDropdown");
return;
}
element.addClass("ui-helper-hidden-accessible");
var selectedValue = element.val() || "";
var list = $("<ul class='sc-dropdownOptions'></ul>");
// Generate dropdown using options in select
$("option", element).each(function (i, o) {
o = $(o);
var html = o.text();
var value = o.attr("value");
var label = o.data("label")
var desc = o.data("description");
if (value) {
list.append("<li data-label='" + label + "' data-value='" + value + "' class='sc-dropdownMainOption " + (selectedValue == value ? "sc-selected " : "") + (desc ? "sc-dropdown-hasDescription " : "") + "'>" + html + (desc ? "<div class='sc-dropdown-description'>" + desc + "</div>" : "") + "</li>");
}
});
var label = $(".sc-selected", list).data("label");
if (!label || label == "undefined") {
label = $(".sc-selected", list).html();
}
parent.append("<div class='sc-selectedDetail'>" + (label || options.defaultLabel) + "</div>");
parent.append(list);
parent.append("<div class='sc-graphics'></div>");
var isVisible = parent.css("display") != "none";
parent.css("display", "inline-block");
if (!isVisible) {
parent.hide();
}
$(document).bind("click", { self: self }, self._click);
$(parent).bind("change", { self: self }, self._change);
$(element).bind("focus", { self: self }, self._focus);
$(element).bind("blur", { self: self }, self._blur);
},
refresh: function refresh() {
var self = this;
var element = self.element;
var options = self.options;
if (options.dontDisplay) {
return;
}
var parent = options.parent;
var selectedValue = element.val() || "";
var list = $(".sc-dropdownOptions", parent);
list.empty();
$("option", element).each(function (i, o) {
o = $(o);
var html = o.html();
var value = o.attr("value");
var label = o.text();
list.append("<li data-label='" + label + "' data-value='" + value + "' class='sc-dropdownMainOption " + (selectedValue == value ? "sc-selected'" : "") + "'>" + html + "</li>");
});
$(".sc-selectedDetail", parent).html($(".sc-selected", list).data("label") || $(".sc-selected", list).html() || "");
},
disable: function disable() {
var self = this;
var element = self.element;
var options = self.options;
var parent = options.parent;
parent.addClass("sc-disabled");
element.attr("disabled", "disabled");
$(".sc-dropdownOptions", parent).slideUp();
},
enable: function enable() {
var self = this;
var element = self.element;
var options = self.options;
var parent = options.parent;
parent.removeClass("sc-disabled");
element.removeAttr("disabled");
},
_click: function _click(event) {
var self = event.data.self;
var element = self.element;
var options = self.options;
var parent = options.parent;
if (parent.is(".sc-disabled") || options.dontDisplay) {
return;
}
var target = $(event.target);
var list = $(".sc-dropdownOptions", parent);
if (target.parents(".sc-dropdown")[0] == parent[0]) {
if (target.is(".sc-selectedDetail") || target.parents(".sc-selectedDetail").length
|| target.is(".sc-graphics") || target.parents(".sc-graphics").length) {
if (list.is(":visible")) {
list.slideUp();
} else {
list.slideDown();
}
} else if (target.is("li:not(.sc-selected)") || target.parents("li:not(.sc-selected)").length) {
var item = target.is("li.sc-dropdownMainOption", parent) ? target : target.parents("li.sc-dropdownMainOption", parent);
element.val(item.data("value"));
$(".sc-selected", list).removeClass("sc-selected");
item.addClass("sc-selected");
$(".sc-selectedDetail", parent).html(item.data("label") || item.html());
list.slideUp();
element.change();
} else {
list.slideUp();
}
element.focus();
} else {
list.slideUp();
}
},
_change: function _change(event) {
var self = event.data.self;
var element = self.element;
var options = self.options;
var parent = options.parent;
if (options.dontDisplay) {
return;
}
var target = $(event.target);
var value = target.val();
var list = $(".sc-dropdownOptions", parent);
var item = $("li.sc-dropdownMainOption[data-value='" + value + "']", parent);
$(".sc-selected", list).removeClass("sc-selected");
item.addClass("sc-selected");
var label = item.data("label");
if (!label || label == "undefined") {
label = item.html();
}
$(".sc-selectedDetail", parent).html(label);
},
_focus: function _focus(event) {
var self = event.data.self;
var element = self.element;
var options = self.options;
var parent = options.parent;
parent.addClass("sc-focus");
},
_blur: function _blur(event) {
var self = event.data.self;
var element = self.element;
var options = self.options;
var parent = options.parent;
parent.removeClass("sc-focus");
}
});
}(jQuery));
If I run this code:
var alts = {};
$('.grid ul').find('.lista-produtos:visible').each(function(){
var classes2 = $(this).attr('class').split(' ');
for (var i = 0; i < classes2.length; i++) {
var matches2 = /^tipo\-(.+)/.exec(classes2[i]);
if (matches2 != null) {
var produto2 = matches2[1];
}
}
if(!alts[classes2]){
alts[classes2] = true;
$('ul.filters').append('<li class="filter-produto">'+ produto2 +'</li>');
}
});
as a function, like this:
function tipoProduto(){
var alts = {};
$('.grid ul').find('.lista-produtos:visible').each(function(){
var classes2 = $(this).attr('class').split(' ');
for (var i = 0; i < classes2.length; i++) {
var matches2 = /^tipo\-(.+)/.exec(classes2[i]);
if (matches2 != null) {
var produto2 = matches2[1];
}
}
if(!alts[classes2]){
alts[classes2] = true;
$('ul.filters').append('<li class="filter-produto">'+ produto2 +'</li>');
}
});
}
and call it here:
$('.list-group-item').click(function(){
var classes1 = $(this).attr('class').split(' ');
for (var i = 0; i < classes1.length; i++) {
var matches1 = /^ctrl\-(.+)/.exec(classes1[i]);
if (matches1 != null) {
var marca1 = matches1[1];
}
}
$(this).addClass("active");
$('.list-group-item').not(this).removeClass("active");
if ($('.todos-produtos').hasClass("active")) {
$('.lista-produtos').hide();
$('.' + marca1).show();
}
else {
var produto1 = $('li.filter-produto.active').text();
$('.lista-produtos').not('.' + marca1 + '.tipo-' + produto1).hide();
$('.' + marca1 + '.tipo-' + produto1).show()
}
tiposProduto(); // CALLING IT HERE //
});
});
then this code below doesn't work:
$(document).ready(function(){
$('.filter-produto').click(function() {
var classes3 = $('.list-group-item.active').attr('class').split(' ');
for (var i = 0; i < classes3.length; i++) {
var matches3 = /^ctrl\-(.+)/.exec(classes3[i]);
if (matches3 != null) {
var marca2 = matches3[1];
}
}
$(this).addClass("active");
$('.filter-produto').not(this).removeClass("active");
if ($(this).hasClass("todos-produtos")) {
$('.' + marca2).show();
}
else {
var produto3 = $(this).text();
$(".lista-produtos").not('.tipo-' + produto3).hide();
$('.' + marca2 + '.tipo-' + produto3).show();
}
});
});
but if I change the 1st code to this:
$(document).ready(function(){
var alts = {};
$('.grid ul').find('.lista-produtos:visible').each(function(){
var classes2 = $(this).attr('class').split(' ');
for (var i = 0; i < classes2.length; i++) {
var matches2 = /^tipo\-(.+)/.exec(classes2[i]);
if (matches2 != null) {
var produto2 = matches2[1];
}
}
if(!alts[classes2]){
alts[classes2] = true;
$('ul.filters').append('<li class="filter-produto">'+ produto2 +'</li>');
}
});
});
then the 4th code works again.
The problem is I need the code above as a function, like I showed on the 2nd and 3rd examples.
Thanks!
Thanks for the few replies. I found out the problem.
Appended objects weren't being recognized by the functions. That's why $('.filter-produto').click(function() { wasn't working.
I need to store form data into an array of objects as a link. Then be able to click the link and fill the form with the objects/data to update or delete.
I'm able to store the form data as objects in an array, but can't figure out how to load it back into the form to update.
var actors = [];
var addActor = function() {
// Assigning Form values to variables
var firstN = $("#fName").val();
var lastN = $("#lName").val();
var gender = $("[name='gender']:checked").val();
var birthdate = $("#birthDate").val();
var action = $("#action").prop('checked');
var comedy = $("#comedy").prop('checked');
var drama = $("#drama").prop('checked');
var sciencefiction = $("#sciencefiction").prop('checked');
var horror =$("#horror").prop('checked');
var suspense = $("#suspense").prop('checked');
// creates newActor variable that contains an object for each input value
var newActor = {fName: firstN, lName: lastN, gender: gender, birthDate: birthdate, action: action, comedy: comedy, drama: drama, suspense: suspense, sciencefiction: sciencefiction, horror: horror}
$("#actorsTable").append("<tr><td><a href='' class='update'>" + newActor.fName + " " + newActor.lName + "</a></td></tr> ");
actors.push(newActor);
console.log(actors);
};
Now my selector function grabs the object but I just don't know how to load it into the form to update and delete. I've been stuck on this for a few days now.
var selectActor = function(e) {
e.preventDefault();
var rowClicked = $(this).parent().parent();
row = rowClicked.index();
alert (actors[row].fName + " " + actors[row].lName + " " + actors[row].gender + " " + actors[row].birthDate + " " + actors[row].action + " " + actors[row].comedy + " " + actors[row].drama + " " + actors[row].suspense + " " + actors[row].sciencefiction + " " + actors[row].horror);
console.log(actors[row]);
};
Here is what I have in action so far. When I check console everything is correct with storing, and selecting, but I can't find anything that shows how to store objects into their respected form fields.
Codepen
Consider using a namespace for your code, then create some generic functions for object manipulations (like an array) as well as some specific to your form.
Note that some libraries like angular, react etc. handle some of this for you, but you asked for the manual part, and it might also be worth some study on one way to do it.
Here is an updated sample to play with: http://codepen.io/MarkSchultheiss/pen/LNqdxK?editors=0010
var myApp = myApp || {};
myApp.arrayObj = {
indexOf: function(myArray, searchTerm, property) {
for (var i = 0; i < myArray.length; i++) {
if (myArray[i][property] === searchTerm) return i;
}
return -1;
},
indexAllOf: function(myArray, searchTerm, property) {
var ai = [];
for (var i = 0; i < myArray.length; i++) {
if (myArray[i][property] === searchTerm) ai.push(i);
}
return ai;
},
lookup: function(myArray, searchTerm, property, firstOnly) {
var found = [];
var i = myArray.length;
while (i--) {
if (myArray[i][property] === searchTerm) {
found.push(myArray[i]);
if (firstOnly) break; //if only the first
}
}
return found;
},
lookupAll: function(myArray, searchTerm, property) {
return this.lookup(myArray, searchTerm, property, false);
},
remove: function(myArray, searchTerm, property, firstOnly) {
for (var i = myArray.length - 1; i >= 0; i--) {
if (myArray[i][property] === searchTerm) {
myArray.splice(i, 1);
if (firstOnly) break; //if only the first term has to be removed
}
}
},
removeByIndex: function(myArray, index) {
myArray.splice(index, 1);
}
};
myApp.func = {
hasDuplicates: function(actor) {
var allLast = myApp.arrayObj.lookup(myApp.data.actors, actor.lName, "lName", false);
var allFirst = myApp.arrayObj.lookup(allLast, actor.fName, "fName", true);
return !!allFirst.length;
},
appendActorRow: function(newActor) {
myApp.data.actorsTable.append("<tr><td><a href='' class='update' data-actorid='" + newActor.actorId + "'>" + newActor.fName + " " + newActor.lName + "</a></td></tr>");
},
getActor: function() {
var newActor = {
fName: $("#fName").val(),
lName: $("#lName").val(),
gender: $("input[type=radio][name='gender']:checked").val(),
birthDate: $("#birthDate").val(),
action: $("#action").prop('checked'),
comedy: $("#comedy").prop('checked'),
drama: $("#drama").prop('checked'),
suspense: $("#suspense").prop('checked'),
sciencefiction: $("#sciencefiction").prop('checked'),
horror: $("#horror").prop('checked'),
actorId: $("#fName").data('actorid')
}
return newActor;
},
putActor: function(actor) {
$("#fName").val(actor.fName);
$("#lName").val(actor.lName);
$("input[type=radio][name='gender']").val(actor.gender);
$("#birthDate").val(actor.birthDate);
$("#action").prop('checked', actor.action);
$("#comedy").prop('checked', actor.comedy);
$("#drama").prop('checked', actor.drama);
$("#suspense").prop('checked', actor.suspense);
$("#sciencefiction").prop('checked', actor.sciencefiction);
$("#horror").prop('checked', actor.horror);
$("#fName").data('actorid', actor.actorId);
},
addActor: function(allowDuplicates) {
var newActor = myApp.func.getActor();
var validActor = false;
if (!allowDuplicates && !myApp.func.hasDuplicates(newActor)) {
validActor = true;
}
if (!validActor && allowDuplicates) {
validActor = true;
}
if (validActor) {
myApp.data.lastActorId = myApp.data.lastActorId + 1;
newActor.actorId = myApp.data.lastActorId;
myApp.func.appendActorRow(newActor);
myApp.data.actors.push(newActor);
}
return newActor;
},
updateRowByIndex: function(actor, index) {
myApp.data.actorsTable.eq(index).html(actor.fName + " " + actor.lName).data("actorid", actor.actorId).addClass('update');
},
updateRowByActorId: function(actor, actorId) {
var r = myApp.data.actorsTable.find('a[data-actorid="' + actorId + '"]');
r.html(actor.fName + " " + actor.lName).data("actorid", actor.actorId).addClass('update');
},
clearForm: function() {
$('#fName').val("");
$('#lName').val("");
$('#birthDate').val("");
$('#form').find('input[type="checkbox"]').prop("checked", false);
$('#form').find('input[type="radio"]').prop("checked", false);
return this;
},
selectActor: function(e) {
e.preventDefault();
var selectActorId = $(this).data('actorid');
var actor = myApp.arrayObj.lookup(myApp.data.actors, selectActorId, "actorId", true)[0];
myApp.func.putActor(actor);
myApp.func.setButtons("old")
},
updateActor: function() {
var actor = myApp.func.getActor();
var index = myApp.arrayObj.indexOf(myApp.data.actors, actor.actorId, "actorId", true);
if (index != -1) {
myApp.data.actors[index] = actor;
myApp.func.updateRowByActorId(actor, actor.actorId);
}
},
deleteActor: function() {
var actor = myApp.func.getActor();
var index = myApp.arrayObj.indexOf(myApp.data.actors, actor.actorId, "actorId", true);
if (index != -1) {
var r = myApp.data.actorsTable.find('a[data-actorid="' + actor.actorId + '"]');
r.parents('tr').remove();
// either will work, used the index one
// myApp.arrayObj.remove(myApp.data.actors, actor.actorId, "actorId", true);
myApp.arrayObj.removeByIndex(myApp.data.actors, index);
}
myApp.func.clearForm().setButtons("new");
// myApp.func.setButtons("new");
},
setButtons: function(foo) {
// if page is new only or form is being filled with new data
// show 'Add Actor' button only
$("#addNewActor").toggle((foo === "new"));
$("#updateActor").toggle(!(foo === "new"));
$("#deleteActor").toggle(!(foo === "new"));
}
};
myApp.data = {
actors: [],
actorsTable: $("#actorsTable"),
lastActorId: 0
};
/* end of myApp */
// Function checks state of page and shows/hides buttons
var actorStatex = function(foo) {
// if page is new only or form is being filled with new data
// show 'Add Actor' button only
$("#addNewActor").toggle((foo === "new"));
$("#updateActor").toggle(!(foo === "new"));
$("#deleteActor").toggle(!(foo === "new"));
};
var validateForm = function(e) {};
$(document).ready(function() {
$('#results').on('click', '.update', myApp.func.selectActor);
$("#birthDate").datepicker();
myApp.func.setButtons("new");
$("#addNewActor").on('click', function() {
var addedActor = myApp.func.addActor(false);
});
$("#updateActor").on('click', myApp.func.updateActor);
$("#deleteActor").on('click', myApp.func.deleteActor);
$("#clearButton").on('click', function() {
myApp.func.clearForm();
myApp.func.setButtons("new");
});
});
it's because the names of your attributes in your alert doesn't match with those in your newActor object.
You should use alert(actors[row].fName) instead of alert(actors[row].fname)
By the way you could make it really simplier using your form id #actorForm
It should be something like this (I have not tested)
var actors = [], index = 0;
$("#addNewActor").click(function() {
var newActor = $('#actorForm').serialize();
$("#actorsTable").append("<tr><td><a href='' class='update'>" + newActor.fName + " " + newActor.lName + "</a></td></tr> ");
actors.push(newActor);
});
// select actor
$(document).on('click', '#actorsTable tr', function() {
if(actors[$(this).index]) {
index = $(this).index();
var actor = actors[index];
// populate your form
}
});
$("#updateActor").click(function() {
var newActor = $('#actorForm').serialize();
actors[index] = newActor;
});
$("#deleteActor").click(function() {
actors.splice(index, 1);
});
After some calculation I am trying to display the results in a table. I tried using .text() and .html() method but none of them working fine on Chrome (FF is perfectly fine).
1) .html() - Doesn't display anything on Chrome
2) .text() - Returns false string
Here is my JS function.
populateHomeGrid: function(categories, day) {
var eventsForTimer = [];
$.each(categories, function(index, value) {
// categoryId -> {raceNumber : event, ...}
var categoryName = value.name, categoryId = value.categoryId,
mapOfEvents = [], maxNumberOfEvents = 0;
// subcategories
$.each(value.categories, function(index, category) {
var mapOfOneCategory = {}, mapSize = 0;
$.each(category.events, function(index, event) {
var raceNumber = event.raceNumber;
mapOfOneCategory[raceNumber] = event;
mapSize++;
});
if (mapSize > maxNumberOfEvents) maxNumberOfEvents = mapSize;
mapOfEvents.push(mapOfOneCategory);
})
maxNumberOfEvents = maxNumberOfEvents;
// drawing main category
var tableId = "home_grid_" + day + "_" + categoryId,
table = $('<table id="' + tableId + '" cellspacing="0" cellpadding="0" width="100%" class="racing_tables" />')
.appendTo($('#' + day))
var tr = $('<tr class="gray"/>')
.appendTo(table)
.append($('<td valign="middle" width="20%"/>')
.append($('<h2/>').html(categoryName)))
for (var i = 1; i <= maxNumberOfEvents; i ++) {
tr.append($('<td valign="middle" />')
.append($('<p/>').html(i)))
}
// drawing sub categories
$.each(mapOfEvents, function(index, event) {
// Drawing row
var firstRow = true, categoryTr;
for (var i = 1; i <= maxNumberOfEvents; i++) {
if (firstRow) {
categoryTr = $('<tr class="white"/>').appendTo(table)
var categoryHolder = $('<td/>').appendTo(categoryTr),
categoryName = $('<p/>').appendTo(categoryHolder)
firstRow = false;
}
if (typeof event[i] != 'undefined') {
categoryName.html(event[i].categoryName);
var categoryId = event[i].categoryId;
(function(i) {
var a = $('<a/>')
.click(function() {racingNavigation.showLocationAndRaceNumber(categoryId, i)})
.data('event', event[i])
.appendTo($('<td />')
.appendTo(categoryTr))
if (racingNavigation.updateHomeCellInfo(a)) eventsForTimer.push(a);
})(i)
}
else {
categoryTr.append($('<td />'))
}
}
})
});
// Setting the counter to update the closing events
var intervalId = setInterval(function() {
$.each(eventsForTimer, function (index, value) {
if (racingNavigation.updateHomeCellInfo(value) == null) {
window.clearInterval(intervalId);
}
})
}, 5000);
intervalIdsForUpdatingHomeGrid.push(intervalId);
},
Function call to racingNavigation.updateHomeCellInfo
updateHomeCellInfo: function(a) {
var info = '', redClass = false,
event = $(a).data('event');
// Killing the interval
if (typeof event == 'undefined') return null;
var timeUtc = event.timeUtc,
status = event.status,
neededForTimer = false;
if (status == 'expired' || status == 'telephone') info = closed;
else if (date.hourDifference(timeUtc) < 1 && date.minDifference(timeUtc) < 1 && date.secDifference(timeUtc) < 2 && (status == 'live' || status == 'run' )) info = closed;
else if (event.result != null) {
var position = 1;
$.each(event.result.winPlaceResults, function() {
var finishingPosition = this.finishingPosition,
selectionNumber = this.selectionNumber;
if (parseInt(finishingPosition) == position) {
info += selectionNumber.toString();
position++;
}
if (position != 4) info += ', ';
if (position == 4) return false;
})
}
else {
neededForTimer = true;
if (date.hourDifference(timeUtc) > 0) {
info = date.formatTime(new Date(timeUtc));
}
else {
info = date.minDifference(timeUtc);
if (info <= 5) redClass = true;
info = date.minDifference(timeUtc) + ' ' + min;
}
}
if (redClass) $(a).parent().addClass('red')
else $(a).parent().removeClass('red');
$(a).html(info);
return neededForTimer;
},
At the end of my second function I am displaying the result $(a).html(info);
where as info contains different element based on the calculations.Default info is set to CLOSED which is defined in another file as var closed = "CLOSED".
I am expecting the table should display string CLOSED when all the different conditions are invalid. Both .text() and .html() method works fine on FF but not on Chrome as explained in the beginning.
I have several dropdown select menus where a selection of the first changes the options of the second and a selection on the second changes the options of the third, and so on.
I would like to remotely simulate a change (i.e. without the user clicking in the select menu) in the dropdown menu which will activate the Javascript to set the next dropdown's options.
Just setting the value of the select menu - document.getElementById('...').value='....' - does not stimulate the Javascript events on the dropdowns.
Note: I do not have access to the Javascript controlling the select menus nor do I know which trigger it looks for on the select menus (I am assuming "onselect").
I am using Javascript and the jQuery library. I need the solution to, of course, work cross browser.
Here is the whole js code (seems to be in prototype) that sets the listeners for the dropdowns:
/**************************** CONFIGURABLE PRODUCT **************************/
Product.Config = Class.create();
Product.Config.prototype = {
initialize: function(config){
this.config = config;
this.taxConfig = this.config.taxConfig;
this.settings = $$('.super-attribute-select');
this.state = new Hash();
this.priceTemplate = new Template(this.config.template);
this.prices = config.prices;
this.settings.each(function(element){
Event.observe(element, 'change', this.configure.bind(this))
}.bind(this));
// fill state
this.settings.each(function(element){
var attributeId = element.id.replace(/[a-z]*/, '');
if(attributeId && this.config.attributes[attributeId]) {
element.config = this.config.attributes[attributeId];
element.attributeId = attributeId;
this.state[attributeId] = false;
}
}.bind(this))
// Init settings dropdown
var childSettings = [];
for(var i=this.settings.length-1;i>=0;i--){
var prevSetting = this.settings[i-1] ? this.settings[i-1] : false;
var nextSetting = this.settings[i+1] ? this.settings[i+1] : false;
if(i==0){
this.fillSelect(this.settings[i])
}
else {
this.settings[i].disabled=true;
}
$(this.settings[i]).childSettings = childSettings.clone();
$(this.settings[i]).prevSetting = prevSetting;
$(this.settings[i]).nextSetting = nextSetting;
childSettings.push(this.settings[i]);
}
// Set default values - from config and overwrite them by url values
if (config.defaultValues) {
this.values = config.defaultValues;
}
var separatorIndex = window.location.href.indexOf('#');
if (separatorIndex != -1) {
var paramsStr = window.location.href.substr(separatorIndex+1);
var urlValues = paramsStr.toQueryParams();
if (!this.values) {
this.values = {};
}
for (var i in urlValues) {
this.values[i] = urlValues[i];
}
}
this.configureForValues();
document.observe("dom:loaded", this.configureForValues.bind(this));
},
configureForValues: function () {
if (this.values) {
this.settings.each(function(element){
var attributeId = element.attributeId;
element.value = (typeof(this.values[attributeId]) == 'undefined')? '' : this.values[attributeId];
this.configureElement(element);
}.bind(this));
}
},
configure: function(event){
var element = Event.element(event);
this.configureElement(element);
},
configureElement : function(element) {
this.reloadOptionLabels(element);
if(element.value){
this.state[element.config.id] = element.value;
if(element.nextSetting){
element.nextSetting.disabled = false;
this.fillSelect(element.nextSetting);
this.resetChildren(element.nextSetting);
}
}
else {
this.resetChildren(element);
}
this.reloadPrice();
// Calculator.updatePrice();
},
reloadOptionLabels: function(element){
var selectedPrice;
if(element.options[element.selectedIndex].config){
selectedPrice = parseFloat(element.options[element.selectedIndex].config.price)
}
else{
selectedPrice = 0;
}
for(var i=0;i<element.options.length;i++){
if(element.options[i].config){
element.options[i].text = this.getOptionLabel(element.options[i].config, element.options[i].config.price-selectedPrice);
}
}
},
resetChildren : function(element){
if(element.childSettings) {
for(var i=0;i<element.childSettings.length;i++){
element.childSettings[i].selectedIndex = 0;
element.childSettings[i].disabled = true;
if(element.config){
this.state[element.config.id] = false;
}
}
}
},
fillSelect: function(element){
var attributeId = element.id.replace(/[a-z]*/, '');
var options = this.getAttributeOptions(attributeId);
this.clearSelect(element);
element.options[0] = new Option(this.config.chooseText, '');
var prevConfig = false;
if(element.prevSetting){
prevConfig = element.prevSetting.options[element.prevSetting.selectedIndex];
}
if(options) {
var index = 1;
for(var i=0;i<options.length;i++){
var allowedProducts = [];
if(prevConfig) {
for(var j=0;j<options[i].products.length;j++){
if(prevConfig.config.allowedProducts
&& prevConfig.config.allowedProducts.indexOf(options[i].products[j])>-1){
allowedProducts.push(options[i].products[j]);
}
}
} else {
allowedProducts = options[i].products.clone();
}
if(allowedProducts.size()>0){
options[i].allowedProducts = allowedProducts;
element.options[index] = new Option(this.getOptionLabel(options[i], options[i].price), options[i].id);
element.options[index].config = options[i];
index++;
}
}
}
},
getOptionLabel: function(option, price){
var price = parseFloat(price);
if (this.taxConfig.includeTax) {
var tax = price / (100 + this.taxConfig.defaultTax) * this.taxConfig.defaultTax;
var excl = price - tax;
var incl = excl*(1+(this.taxConfig.currentTax/100));
} else {
var tax = price * (this.taxConfig.currentTax / 100);
var excl = price;
var incl = excl + tax;
}
if (this.taxConfig.showIncludeTax || this.taxConfig.showBothPrices) {
price = incl;
} else {
price = excl;
}
var str = option.label;
if(price){
if (this.taxConfig.showBothPrices) {
str+= ' ' + this.formatPrice(excl, true) + ' (' + this.formatPrice(price, true) + ' ' + this.taxConfig.inclTaxTitle + ')';
} else {
str+= ' ' + this.formatPrice(price, true);
}
}
return str;
},
formatPrice: function(price, showSign){
var str = '';
price = parseFloat(price);
if(showSign){
if(price<0){
str+= '-';
price = -price;
}
else{
str+= '+';
}
}
var roundedPrice = (Math.round(price*100)/100).toString();
if (this.prices && this.prices[roundedPrice]) {
str+= this.prices[roundedPrice];
}
else {
str+= this.priceTemplate.evaluate({price:price.toFixed(2)});
}
return str;
},
clearSelect: function(element){
for(var i=element.options.length-1;i>=0;i--){
element.remove(i);
}
},
getAttributeOptions: function(attributeId){
if(this.config.attributes[attributeId]){
return this.config.attributes[attributeId].options;
}
},
reloadPrice: function(){
var price = 0;
var oldPrice = 0;
for(var i=this.settings.length-1;i>=0;i--){
var selected = this.settings[i].options[this.settings[i].selectedIndex];
if(selected.config){
price += parseFloat(selected.config.price);
oldPrice += parseFloat(selected.config.oldPrice);
}
}
optionsPrice.changePrice('config', {'price': price, 'oldPrice': oldPrice});
optionsPrice.reload();
return price;
if($('product-price-'+this.config.productId)){
$('product-price-'+this.config.productId).innerHTML = price;
}
this.reloadOldPrice();
},
reloadOldPrice: function(){
if ($('old-price-'+this.config.productId)) {
var price = parseFloat(this.config.oldPrice);
for(var i=this.settings.length-1;i>=0;i--){
var selected = this.settings[i].options[this.settings[i].selectedIndex];
if(selected.config){
var parsedOldPrice = parseFloat(selected.config.oldPrice);
price += isNaN(parsedOldPrice) ? 0 : parsedOldPrice;
}
}
if (price < 0)
price = 0;
price = this.formatPrice(price);
if($('old-price-'+this.config.productId)){
$('old-price-'+this.config.productId).innerHTML = price;
}
}
}
}
all the select menus have the class "super-attribute-select"
For this
<select name="blah">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
You would
$('select[name="blah"]').val(3).trigger('change');
Don't know if you're looking for .trigger('select'); or trigger('onselect'); but I've never used those.
Demo
Somethinkg like this may work:
$('select option[value=yourValue]').click();
Or:
$('select').find('option[value=yourValue]').attr('selected', 'selected').end().trigger('onselect');