I have a call in the parent HTML which invokes a javascript call.
<div class="data">
<form:input title="Building" styleClass="content contractorDisable" maxlength="5" size="6" path="fireImpairForm.bldCode" />
<a href="javascript:winOpen('LookupLocation.htm','bld')">
<img src="image/search.gif" border="0" alt="Click here to find Building"></a>
</div>
The javascript used for the modal window previously was using a window.showModal where the code has been commented as shown in the javascript code below.
I am looking to have a replacement for this same call through Jquery and using the jQuery dialog code.
and this is the javascript call that is called which encapsulates a jquery dialog popup. Previously I was able to set a value in the parent input text value to whatever was selected in the modalDialog window using the return object of modalwindow.That code is now commented out to show what it was and what the implementation I am looking for in its place. I am looking for some replacement for that implementation using jQuery dialog. My Dailog is encapsulating another jsp which is a table so I am not able to return the value back to the parent form.
function winOpen(urlVal, type) {
var printNames = new Object();
var ind = [document.forms[0].elements["fireImpairForm.statusId"].selectedIndex].value;
ind = document.forms[0].elements["fireImpairForm.facility"].selectedIndex;
var facilityCode = document.forms[0].elements["fireImpairForm.facility"].item(ind).value;
var sub = facilityCode.substring(((facilityCode).indexOf("-")) + 1, (facilityCode).length);
var params = "?bldCode=" + document.forms[0].elements["fireImpairForm.bldCode"].value + "&floorCode=" + document.forms[0].elements["fireImpairForm.floorCode"].value + "&campusCode=" + sub + "&check=" + "check" + "&facilityCode=" + facilityCode;
/*
retObj = window.showModalDialog(urlVal+params,"","scroll:no;status:no;dialogWidth:620px;dialogHeight:600px;unadorned:yes;resizable=yes");
if (retObj != null) {
document.forms[0].elements["fireImpairForm.bldCode"].value=retObj.code;
}
*/
}
var page = urlVal + params;
var $dialog = $('<div></div>')
.html('<iframe style="border: 0px; " src="' + page + '" width="100%" height="100%"></iframe>')
.dialog({
autoOpen: false,
modal: true,
height: 625,
width: 500,
title: "Buildings"
});
$dialog.dialog('open');
}
The LookupLocation.htm spring controller returns a jsp
<BODY topmargin=0 leftmargin=0 bottommargin=0 rightmargin=0>
<center>
<form name="locForm">
<input type="hidden" name="code" />
<DIV style="overflow:auto;clear:both; width:100%; height:525px; border :1px solid;">
<TABLE onkeydown="if (event.keyCode=='13') return returnToParent()" cellpadding="0" cellspacing="1" id="resultTable" width="100%">
<TBODY>
<c:if test="${empty resultList}">
<tr>
<td bgcolor="buttonface"><b>No data found</b></td>
</tr>
</c:if>
<c:if test="${!empty resultList}">
<tr>
<td> </td>
</tr>
<tr>
<td class="label">Search:</td>
<td class="content">
<input name="searchFld" type="text" size=15 onChange="">
</td>
<td class="content">
<input type="button" value="Find" onclick="findString(document.locForm.searchFld.value)">
</td>
</tr>
<tr>
<td nowrap class="searchTableHeader" align="center" STYLE="color:white">Select</td>
<td nowrap class="searchTableHeader" align="center" STYLE="color:white">Location Code</td>
<td nowrap class="searchTableHeader" align="center" STYLE="color:white">Description</td>
</tr>
<c:set var="evenCount" value="${0}" />
<c:forEach var="result" varStatus="i" items="${resultList}">
<c:set var="evenCount" value="${evenCount+1}" />
<c:choose>
<c:when test="${evenCount % 2 == 0}">
<tr id='row${evenCount}' class="even_row">
</c:when>
<c:otherwise>
<tr id='row${evenCount}' class="odd_row">
</c:otherwise>
</c:choose>
<td width="5%" align="center" class="content">
<input type="radio" name="radioValue" onclick='highlight(${evenCount}); setLookupValuesOne("${result.code}");returnToParent();'>
</td>
<td width="15%" nowrap class="content">
<c:out value="${result.code}" />
</td>
<td nowrap class="content">
<c:out value="${result.description}" />
</td>
</tr>
</c:forEach>
</c:if>
</TBODY>
</TABLE>
</DIV>
</form>
</center>
</BODY>
Any help will be much appreciated.
I have looked at several implementation of jQuery Dialogs and I am not able to piece together how I can have parent form interaction between the jQuery Dialog.
UPDATED :adding the rendered HTML requested by Mark
Here is the updated rendered HTML.
Normal behaviour was , when radio button is selected, the window closed and returned the selected object which was set to a input value on the parent form but now the return object is not getting captured and I can not set the input value fireImpairForm.bldCode
<html>
<BODY topmargin=0 leftmargin=0 bottommargin=0 rightmargin=0>
<center>
<form name="locForm">
<input type="hidden" name="code" />
<DIV style="overflow:auto;clear:both; width:100%; height:525px; border :1px solid;">
<TABLE onkeydown="if (event.keyCode=='13') return returnToParent()" cellpadding="0" cellspacing="1" id="resultTable" width="100%">
<TBODY>
<tr>
<td> </td>
</tr>
<tr>
<td class="label">Search:</td>
<td class="content">
<input name="searchFld" type="text" size=15 onChange="">
</td>
<td class="content">
<input type="button" value="Find" onclick="findString(document.locForm.searchFld.value)">
</td>
</tr>
<tr>
<td nowrap class="searchTableHeader" align="center" STYLE="color:white">Select</td>
<td nowrap class="searchTableHeader" align="center" STYLE="color:white">Location Code</td>
<td nowrap class="searchTableHeader" align="center" STYLE="color:white">Description</td>
</tr>
<tr id='row1' class="odd_row">
<td width="5%" align="center" class="content">
<input type="radio" name="radioValue" onclick='highlight(1); setLookupValuesOne("PC ");returnToParent();'>
</td>
<td width="15%" nowrap class="content">PC </td>
<td nowrap class="content">10150 Place</td>
</tr>
<tr id='row2' class="even_row">
<td width="5%" align="center" class="content">
<input type="radio" name="radioValue" onclick='highlight(2); setLookupValuesOne("ON ");returnToParent();'>
</td>
<td width="15%" nowrap class="content">ON </td>
<td nowrap class="content">1019 Building</td>
</tr>
<tr id='row3' class="odd_row">
<td width="5%" align="center" class="content">
<input type="radio" name="radioValue" onclick='highlight(3); setLookupValuesOne("OG ");returnToParent();'>
</td>
<td width="15%" nowrap class="content">OG </td>
<td nowrap class="content">19137 Building</td>
</tr>
<tr id='row4' class="even_row">
<td width="5%" align="center" class="content">
<input type="radio" name="radioValue" onclick='highlight(4); setLookupValuesOne("TO ");returnToParent();'>
</td>
<td width="15%" nowrap class="content">TO </td>
<td nowrap class="content">2011 Building</td>
</tr>
<tr id='row5' class="odd_row">
<td width="5%" align="center" class="content">
<input type="radio" name="radioValue" onclick='highlight(5); setLookupValuesOne("TT ");returnToParent();'>
</td>
<td width="15%" nowrap class="content">TT </td>
<td nowrap class="content">30133 4 nw Street Building</td>
</tr>
<tr id='row6' class="even_row">
<td width="5%" align="center" class="content">
<input type="radio" name="radioValue" onclick='highlight(6); setLookupValuesOne("TH ");returnToParent();'>
</td>
<td width="15%" nowrap class="content">TH </td>
<td nowrap class="content">13939 Warehouse</td>
</tr>
<tr id='row7' class="odd_row">
<td width="5%" align="center" class="content">
<input type="radio" name="radioValue" onclick='highlight(7); setLookupValuesOne("N2 ");returnToParent();'>
</td>
<td width="15%" nowrap class="content">N2 </td>
<td nowrap class="content">40th Avenue Warehouse</td>
</tr>
</TBODY>
</TABLE>
</DIV>
</form>
</center>
</BODY>
</html>
Here the jscript calls if that helps.
I am having a time trying to format the three jscript calls . If you need it I will paste it somehow. They are not really important though for what I am asking. The first is highlighting grey and white background depending on selected row number odd or even. The next ones I have added
function returnToParent() {
//var defer=$.Deferred();
if (document.forms[0].code.value == null || document.forms[0].code.value == "") {
alert("Please select a row.");
return false;
}
var rowObj = new Object();
rowObj.code = document.forms[0].code.value;
if (window.showModalDialog) {
self.returnValue = rowObj;
} else {
//opener.setData(rowObj);
}
//defer.resolve("true");//this text 'true' can be anything. But for this usage, it should be true or false.
//$(window.opener.document).forms['dialogForm'].dailogFormVal.val=document.forms[0].code.value;
//$(window.opener.document).find().val(document.forms[0].code.value);
var parent = $(window.frameElement).parent();
parent.find("#dailogFormVal").val(document.forms[0].code.value);
$(this).dialog("close");
}
function setLookupValuesOne(codeValue) {
document.forms[0].code.value = codeValue;
var parent = $(window.frameElement).parent();
parent.find("#dailogFormVal").val(document.forms[0].code.value);
//$(window.parent.document.getElementById("dailogFormVal")).val(document.forms[0].code.value);
//$(window.opener.document).forms['dialogForm'].getElementById['dailogFormVal'].value=codeValue;
The finally ending "}" is not getting added to the jscript code.
Updated to show the modified jScript
console.clear();$dialog.append("<iframe id='dialogframe' style='border: 0px; width: 100%;height:100% '/>");$dialog.dialog({autoOpen: false, modal: true,width: "auto", height: "auto", title: "Buildings", buttons: [{
text: "Close", click: function() { $(this).dialog('close'); } }]});function winOpenDlg(urlVal, type) { var printNames = new Object(); var ind =[document.forms[0].elements["fireImpairForm.statusId"].selectedIndex].value; ind = document.forms[0].elements["fireImpairForm.facility"].selectedIndex; var facilityCode = document.forms[0].elements["fireImpairForm.facility"].item(ind).value; var sub = facilityCode.substring(((facilityCode).indexOf("-"))+1,(facilityCode).length); if (type == 'floor') { if (document.forms[0].elements["fireImpairForm.bldCode"].value.length <= 0) { alert('Please select a building.'); }else { var params="?bldCode="+document.forms[0].elements["fireImpairForm.bldCode"].value+"&campusCode="+sub+"&facilityCode="+facilityCode;
}
} else if (type == 'room') {
if (document.forms[0].elements["fireImpairForm.bldCode"].value.length <= 0) {
alert('Please select a building.');
}else if (document.forms[0].elements["fireImpairForm.floorCode"].value.length <= 0) {
alert('Please select a floor.');
}else {
var params="?bldCode="+document.forms[0].elements["fireImpairForm.bldCode"].value+"&floorCode="+document.forms[0].elements["fireImpairForm.floorCode"].value+"&campusCode="+sub+"&check="+"check"+"&facilityCode="+facilityCode;
}
} else {
var params="?campusCode="+sub+"&facilityCode="+facilityCode;
}var page = urlVal + params; $('#dialogframe').attr('src', page);// yours would do this // here I create a sample set of text to inject //var sample = '<div id="findem">Hi I am found</div>';var dialogBody = $("#dialogframe").contents().find("body");//$($dialog.find('#dialogframe')[0].contentWindow.document.body);//$('#dialogframe').attr('src', page);// yours would do this // I do this for simplicity and demonstration//dialogBody.html("<div id='original'>First Text </div>"); //dialogBody.append(sample);// add a click event to the dialog contents, you would do different things dialogBody.on('click', '[id^=row]', function() { console.log("triggered !!");
console.log(this.id + ":" + this.innerHTML); // id of element clicked document.forms[0].elements["fireImpairForm.bldCode"]=document.forms[0].elements[this.id].value;}); $dialog.dialog('open');}
Updated to show latest Javascript
I updated my code and removed any reference to my src location but even then the same error comes up.
EditFireImpair.htm?permitIk=301 Uncaught TypeError: Cannot read property 'contentWindow' of undefined
Defined below is the java script code I inserted almost unchanged from what you posted. The dialog does not open up as it does on your fiddle page.
<script>
console.clear();
var $dialog = $('#mydialog');
$dialog.append("<iframe id='dialogframe' style='border: 0px; width: 100%;height:100% '/>");;
$dialog.dialog({
autoOpen: false,
modal: true,
width: "auto",
height: "auto",
title: "Buildings",
buttons: [{
text: "Close Me",
click: function() {
$(this).dialog('close');
}
}]
});
function winOpenNewDlg(urlVal, type) {
var printNames = new Object();
var ind =[document.forms[0].elements["fireImpairForm.statusId"].selectedIndex].value;
ind = document.forms[0].elements["fireImpairForm.facility"].selectedIndex;
var facilityCode = document.forms[0].elements["fireImpairForm.facility"].item(ind).value;
var sub = facilityCode.substring(((facilityCode).indexOf("-"))+1,(facilityCode).length);
if (type == 'floor') {
if (document.forms[0].elements["fireImpairForm.bldCode"].value.length <= 0) {
alert('Please select a building.');
}else {
var params="?bldCode="+document.forms[0].elements["fireImpairForm.bldCode"].value+"&campusCode="+sub+"&facilityCode="+facilityCode;
}
} else if (type == 'room') {
if (document.forms[0].elements["fireImpairForm.bldCode"].value.length <= 0) {
alert('Please select a building.');
}else if (document.forms[0].elements["fireImpairForm.floorCode"].value.length <= 0) {
alert('Please select a floor.');
}else {
var params="?bldCode="+document.forms[0].elements["fireImpairForm.bldCode"].value+"&floorCode="+document.forms[0].elements["fireImpairForm.floorCode"].value+"&campusCode="+sub+"&check="+"check"+"&facilityCode="+facilityCode;
}
} else {
var params="?campusCode="+sub+"&facilityCode="+facilityCode;
}
var page = urlVal + params;
//$('#dialogframe').attr('src', page);// yours would do this
// here I create a sample set of text to inject
var sample = '<div id="findem">Hi I am found</div>';
var dialogBody = $($dialog.find('#dialogframe')[0].contentWindow.document.body);
// $('#dialogframe').attr('src', page);// yours would do this
// I do this for simplicity and demonstration
dialogBody.html("<div id='original'>First Text </div>");
dialogBody.append(sample);
// add a click event to the dialog contents, you would do different things
dialogBody.on('click', '*', function() {
console.log("triggered !!");
console.log(this.id + ":" + this.innerHTML); // id of element clicked
document.forms[0].elements["fireImpairForm.bldCode"]=document.forms[0].elements[this.id].value;
});
$dialog.dialog('open');
}
</script>
and this is the HTML
<div style="display:none; visibility:hidden;">
<div id="mydialog">
<input type="hidden" id="bldCode" />
</div>
</div>
<a href="javascript:winOpenNewDlg('LookupLocation.htm','bld')">
<img src="image/search.gif" border="0"
alt="Click here to find Building"></a>
Ok rather than dig into your details let us start with a very simplified example with some comments: See and play with it here: https://jsfiddle.net/MarkSchultheiss/kkwpb5b7/
EDIT: Note how I put a click event in my code on the dialog content. This is similar to your 'click something/event of something etc) that you wish to do.
I put a simple svg icon in, yours is a gif (so we have something to click).
Markup (for my examples, yours differs a bit)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<div class="data">
<form:input title="Building" styleClass="content contractorDisable" maxlength="5" size="6" path="fireImpairForm.bldCode" />
<a class='lookuplocation' data-url="LookupLocation.htm" ,data-type="bld">
<img border="0" alt="Click here to find Building">
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
<circle cx="50" cy="50" r="25" stroke="black" stroke-width="5" fill="red" />
</svg>
</a>
</div>
<div style="display:none; visibility:hidden;">
<div id="mydialog">
</div>
</div>
Now see my "hidden" dialog wrapper? let's use that rather than some in-line script and then inject some content into that (you would use the src)
var $dialog ={};
$(document).ready(function()(
$dialog = $('#mydialog');
$dialog.append("<iframe id='dialogframe' style='border: 0px; width: 100%;height:100% '/>");;
$dialog.dialog({
autoOpen: false,
modal: true,
width: "auto",
height: "auto",
title: "Buildings",
buttons: [{
text: "Close Me",
click: function() {
$(this).dialog('close');
}
}]
});
});
function winOpen(urlVal, type) {
var params = '?bldCode=howdy'; // put your stuff in here
var page = urlVal + params;
// $('#dialogframe').attr('src', page);// yours would do this
// here I create a sample set of text to inject
var sample = '<div id="findem">Hi I am found</div>';
var dialogBody = $($dialog.find('#dialogframe')[0].contentWindow.document.body);
// $('#dialogframe').attr('src', page);// yours would do this
// I do this for simplicity and demonstration
dialogBody.html("<div id='original'>First Text </div>");
dialogBody.append(sample);
// add a click event to the dialog contents, you would do different things
dialogBody.on('click', '*', function() {
console.log("triggered !!");
console.log(this.id + ":" + this.innerHTML); // id of element clicked
});
$dialog.dialog('open');
}
// took this out of the markup because I don't like them there.
$('.data').on('click', 'a.lookuplocation', function() {
winOpen($(this).data('url'), $(this).data('type'));
});
Related
function disableField()
{
var Count = $('#dataTable tr').length;
if (Count == 2){
$("input").not('.DeleteButton').prop('disabled', false);
}else{
$("input").prop('disabled', false);
}
}
//--------------------------------------------------
var regex = /^([a-zA-Z0-9 _-]+)$/;
var cindex = 0;
var quicklink = '' ;
$(document).on('click','.Buttons', function(addrow) {
var count = $('table tr:last input:text').filter((_,el) => el.value.trim() == "").length;
if(count || !$('.id_100 option[value=code]').attr('selected','selected')){
alert("Please fill the current row");
return false;
}
var $tr = $('#dataTable tbody tr:last');
var $clone = $tr.clone(true);
cindex++;
$clone.find(':input').not('select').not('.DeleteButton').val('').attr('disabled', true);
$clone.attr('id', 'id'+(cindex) ); //update row id if required
//update ids of elements in row
$clone.find("*").each(function() {
var id = this.id || "";
if(id != ""){
var match = id.match(regex) || [];
if (match.length == 2) {
this.id = this.name + (cindex);
}
}
});
$tr.after($clone);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table cellspacing="0" cellpadding="0" border="0" id="mainbox" class="mainbox"><tr><td>
<div class="toppanel"><ul><li></li></ul></div>
<div class="abcd"> <!--mainbox middlepanel start-->
<table cellspacing="0" cellpadding="0" border="0" id="maintable" class="maintable">
<tr>
<td valign="top">
<div id="pageheadingpanel">
<div id="pageheading">Quick Link Widget Configuration</div>
<div id="pageheadingdate"><xsl:call-template name="formatted_date"/></div>
</div>
</td>
</tr>
<tr>
<td height="100%" valign="top">
<div class="y_scroll" id="contentarea">
<div class="contentarea"><!--contentarea start-->
<span id="box" class="box"> <!--rounded curve/border start-->
<div class="middlepanel"> <!--contentarea box middlepanel start-->
<div style="display:block" id="textBox1" >
<span id="box1" class="box">
<div class="toppanel"><ul><li></li></ul></div>
<div class="middlepanel">
<table border="0" cellspacing="1" cellpadding="1" id="dataTable" name="dataTable" class="graphtable">
<thead>
<tr>
<td class="headingalign" width="16%">Links</td>
<td class="headingalign" width="32%">Desciption</td>
<td class="headingalign" width="16%">Image</td>
<td class="headingalign" width="16%">URL</td>
<td class="headingalign" width="05%"></td>
</tr>
</thead>
<tbody>
<tr id="id0" class="vals" name="id0">
<td>
<div class="id_100">
<select type="select-one" id='fldsearch' class="objselect" name="fldsearch" onChange="disableField()" >
<option value="">Select</option>
<xsl:for-each select="values from local db">
<xsl:sort order="ascending" select="description"/>
<option value="{description}">
<xsl:value-of select="description"/>
</option>
</xsl:for-each>
</select>
</div> </td>
<td>
<input id="flddesc" name="flddesc" maxlength="500" disabled="true" class="objinputtext1" size="85" value="{//RESPONSE}" />
</td>
<td>
<input id="fldimg" name="fldimg" maxlength="50" disabled="true" class="objinputtext2" size="35" value="{//RESPONSE}" />
</td>
<td>
<input id="fldurl" name="fldurl" maxlength="15" disabled="true" class="objinputtext3" size="35" value="{//RESPONSE}" />
</td>
<td>
<input tabindex="6" value="Delete Row" disabled="true" class="DeleteButton" type="button" />
</td>
</tr>
</tbody>
</table>
<div class="buttonarea">
<ul>
<li><input tabindex="6" id="Button3" value="Add New Row" class="Buttons" name="Button3" type="button" /></li>
</ul>
</div>
I have a table with a drop-down column in it. Whenever i change the values of drop-down my corresponding fields get enabled. The problem i am getting is if i change the values of my drop-down of previous row the columns of current row also get enabled.Any help will be appreciated. Thanks.
Edit:I have added 'Add Row' function too in my code.
I have added some changes in your disableField function. Pass parameter(this) disableField(this) in that function on chnage event.
function disableField(elem)
{
var Count = $('#dataTable tr').length;
if (Count == 2){
$(elem).closest('tr').find("input").not('.DeleteButton').prop('disabled', false);
}
else{
$(elem).closest('tr').find("input").prop('disabled', false);
}}
//--------------------------------------------------
var regex = /^([a-zA-Z0-9 _-]+)$/;
var cindex = 0;
var quicklink = '' ;
$(document).on('click','.Buttons', function(addrow) {
var count = $('table tr:last input:text').filter((_,el) => el.value.trim() == "").length;
if(count || !$('.id_100 option[value=code]').attr('selected','selected')){
alert("Please fill the current row");
return false;
}
var $tr = $('#dataTable tbody tr:last');
var $clone = $tr.clone(true);
cindex++;
$clone.find(':input').not('select').attr('disabled', true);
$clone.attr('id', 'id'+(cindex) ); //update row id if required
//update ids of elements in row
$clone.find("*").each(function() {
var id = this.id || "";
if(id != ""){
var match = id.match(regex) || [];
if (match.length == 2) {
this.id = this.name + (cindex);
}
}
});
$tr.after($clone);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table cellspacing="0" cellpadding="0" border="0" id="mainbox" class="mainbox"><tr><td>
<div class="toppanel"><ul><li></li></ul></div>
<div class="abcd"> <!--mainbox middlepanel start-->
<table cellspacing="0" cellpadding="0" border="0" id="maintable" class="maintable">
<tr>
<td valign="top">
<div id="pageheadingpanel">
<div id="pageheading">Quick Link Widget Configuration</div>
<div id="pageheadingdate"><xsl:call-template name="formatted_date"/></div>
</div>
</td>
</tr>
<tr>
<td height="100%" valign="top">
<div class="y_scroll" id="contentarea">
<div class="contentarea"><!--contentarea start-->
<span id="box" class="box"> <!--rounded curve/border start-->
<div class="middlepanel"> <!--contentarea box middlepanel start-->
<div style="display:block" id="textBox1" >
<span id="box1" class="box">
<div class="toppanel"><ul><li></li></ul></div>
<div class="middlepanel">
<table border="0" cellspacing="1" cellpadding="1" id="dataTable" name="dataTable" class="graphtable">
<thead>
<tr>
<td class="headingalign" width="16%">Links</td>
<td class="headingalign" width="32%">Desciption</td>
<td class="headingalign" width="16%">Image</td>
<td class="headingalign" width="16%">URL</td>
<td class="headingalign" width="05%"></td>
</tr>
</thead>
<tbody>
<tr id="id0" class="vals" name="id0">
<td>
<div class="id_100">
<select type="select-one" id='fldsearch' class="objselect" name="fldsearch" onChange="disableField(this)" >
<option value="">Select</option>
<xsl:for-each select="values from local db">
<xsl:sort order="ascending" select="description"/>
<option value="{description}">
<xsl:value-of select="description"/>
</option>
</xsl:for-each>
</select>
</div> </td>
<td>
<input id="flddesc" name="flddesc" maxlength="500" disabled="true" class="objinputtext1" size="85" value="{//RESPONSE}" />
</td>
<td>
<input id="fldimg" name="fldimg" maxlength="50" disabled="true" class="objinputtext2" size="35" value="{//RESPONSE}" />
</td>
<td>
<input id="fldurl" name="fldurl" maxlength="15" disabled="true" class="objinputtext3" size="35" value="{//RESPONSE}" />
</td>
<td>
<input tabindex="6" value="Delete Row" disabled="true" class="DeleteButton" type="button" />
</td>
</tr>
</tbody>
</table>
<div class="buttonarea">
<ul>
<li><input tabindex="6" id="Button3" value="Add New Row" class="Buttons" name="Button3" type="button" /></li>
</ul>
</div>
All in all there is to much extraneous code so the following answer has different code yet can be applied to the clunky code provided in question. I recommend that your code be more streamlined like the following demo provided in this answer.
Here's some suggestions:
If you are using multiple form controls (ex. <button>, <input>, <textarea>, <select>, etc), wrap everything into a <form>
If you have multiple tags (aka elements) that the user can click, submit, reset, change, input, etc register the events to the <form>
In order to find the exact form control that was clicked, changed, etc. use the Event.target property to find it or this keyword and the Event.data parameter.
$('form selector').on('event type', Event.data, callback function)
The #id and [name] attributes are unnecessary unless you are using certain Web APIs such as HTMLFormControlsCollection or HTMLFormElement
Never use event attributes (ex onchange="callback()") when using jQuery. Use the proper jQuery method or .on() method.
// jQuery method
$(selector).click(callback)
// .on() method
$(selector).on('click', callback)
Minor details:
The [type] attribute does not apply to the <select> tag.
Use <th> instead of <td> within <thead>
[maxlength] of 500 is ridiculous. Use <textarea> instead of <input>
Details are commented in demo
/*
Register form.io to the 'submit', 'click', and 'change' events
Note the callback function does not have `()` suffixed because it would be
interpreted as: "run function now"
The callback function doesn't run immediately it runs when a registered event is triggered.
*/
$('.io').on('submit click change', eventHandler);
// Define the counter
let counter = 0;
// Always pass the Event Object when defining a callback function
function eventHandler(event) {
// The Event Object has several properties...
// Get the type of event triggered (ie submit, change, or click)
let eType = event.type;
/*
Get the origin element of event
if 'submit' target will be <form>
if 'click' target will be <button>
if 'change' target will be <select>
*/
let eNode = event.target;
// Pass the event type through a switch() function...
switch (eType) {
// if type is 'submit'...
case 'submit':
// Create a deep clone of the first row
let clone = $('.grid tr:first-child').clone(true, true);
// Add clone as the last child of the <tbody>
$('.grid').append(clone);
// On .each() elment with class '.data' found within the clone...
clone.find('.data').each(function(i) {
// disable it
this.disabled = true;
// remove its value
this.value = '';
});
// Increment the counter by 1
counter++;
// Dereference the clone and assign id as row+counter
clone[0].id = `row${counter}`;
/*
Prevent default behavior:
Reset <form>
Send data to a server
*/
event.preventDefault();
// Stop event from bubbling any further up the event chain
event.stopPropagation();
// ...otherwise skip this case and continue onto the next case
break;
// if type is 'click'...
case 'click':
// if the clicked element (ie <button>) has class: '.del'...
if ($(eNode).hasClass('del')) {
// Get the clicked <button>'s ancestor <tr>
let row = $(eNode).closest('tr');
// if that <tr> is NOT the first <tr>...
if (row.index() !== 0) {
// remove the <tr>
row.remove();
}
}
event.stopPropagation();
break;
// if type is 'change'...
case 'change':
// if changed element (ie <select>) class is '.type'...
if ($(eNode).hasClass('type')) {
// Get the changed <select>'s ancestor <tr>
let row = $(eNode).closest('tr');
// if changed <select>'s value is NOT "X" return true otherwise return false
let pick = eNode.value !== "X" ? true : false;
/*
On .each() element with class .data within the <tr>
disable the .data if <select>'s value is "X"
Otherwise enable the .data
and then remove the .data value
*/
row.find('.data').each(function(i) {
this.disabled = !pick;
this.value = '';
});
}
event.stopPropagation();
break;
default:
event.stopPropagation();
break;
}
}
:root {
font: 400 3vw/1.2 Arial
}
form {
width: max-content;
margin: 10px auto
}
table {
table-layout: fixed;
border-collapse: separate;
border-spacing: 4px;
width: 90vw
}
th:first-of-type {
width: 20%
}
th:nth-of-type(2) {
width: 35%
}
th:nth-of-type(3) {
width: 35%
}
th:last-of-type {
width: 10%
}
td {
padding: 0 8px
}
select,
textarea,
button {
display: block;
min-width: 97%;
min-height: 1.2rem;
font-size: initial;
}
select {
padding: 2px 0 2px 2px
}
textarea {
resize: vertical;
overflow-y: auto;
overflow-x: hidden
}
<form class='io'>
<table>
<thead>
<tr>
<th>Type</th>
<th>Desciption</th>
<th>Image/URL</th>
<th><button>➕</button></th>
</tr>
</thead>
<tbody class='grid'>
<tr>
<td>
<select class='type'>
<option value="X" default></option>
<option value="GDS">Guides</option>
<option value="PRO">Promos</option>
<option value="TEM">Templates</option>
<option value="VID">Videos</option>
</select>
</td>
<td><textarea class='desc data' rows='1' cols='20' disabled></textarea></td>
<td><textarea class='urls data' rows='1' cols='20' disabled></textarea></td>
<td><button class='del' type='button'>❌</button></td>
</tr>
</tbody>
</table>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
I got few buttons question and would like to change the txt color after the value changed. ex: begin with "select" --> changes to "positive" (answer).
where should I make the loop to check if the value was changed? how?
I'm stuck on this code and any help will be good.
var answers = ['Positive', 'Negative'];
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);
if(ARRAY_OF_QUESTIONS[i].header == 'undefined'){
$("#" + id + "-inspectionResult").text(data.inspectionResult || 'Select').addClass(asnwers)
} // loop check for value
if (asnwers) {
}
}
else {
$('#questionsTable tbody').append(Utils.processTemplate("#sectionRowTemplate tbody", data));
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table frame="box" id="questionnaireHeader" width="100%'" position="fixed">
<tr height="40px" style="background: #006b54; color:white" >
<td width="70%" align="center" style="align:center">Question</div>
<td width="30%" align="center" style="align:center">Result</td>
</tr>
</table>
<table frame="box" width="100%" id="questionsTable">
<tbody>
</tbody>
</table>
<!-- This hosts all HTML templates that will be used inside the JavaScript code -->
<table class ="cls-{id} active-{active}" style="display:none;" width="100%" id="rowTemplate">
<tr class ="bb cls-{id} active-{active}">
<td class="active-{active}" id="{id}-question" width="70%">{question}</td>
<td class="cls-{id} active-{active}" style="border-style:hidden; font-family: 'Poppins', sans-serif !important;" width="30%">
<button class="buttons" step="0.01" data-clear-btn="false" style="background: #006b54; border radius: px; color:white !important ;" id="{id}-inspectionResult"></button>
</td>
</tr>
</table>
<div id="projectPopUp" class="popup-window" style="display:none;">
<div class="popuptitle" id="details-name"></div>
<table id="detailsgrid">
<tbody></tbody>
</table>
<div>
<button class="smallButton" onClick="closePopup()">Close</button>
</div>
</div>
<table style="display:none;" id="popupPersonTemplate">
<tr class ="bb cls-{id}">
<td width="70%">{name}</td>
<td width="30%">
<button class="buttons" step="0.01" data-clear-btn="false" style="background: #006b54; color:white !important ;" id="{id}-status"></button>
</td>
</tr>
</table>
<!--closeProjectPopup()-->
<table style="display: none;" id="sectionRowTemplate">
<tr width="100%" class="bb cls-{id}-row2 sectionheader">
<td class="cls-{id}" colspan="3">{question}</td>
</tr>
</table>
its done!
var checkComplete = true;
var questionResults = data.employee_results;
for (var employee in questionResults){
if (questionResults[employee] == ''){
checkComplete = false;
}
}
if (checkComplete) {
//button
$("#" + id + "-inspectionResult").text('Done');
}
else {
$("#" + id + "-inspectionResult").text('Select');
}
}
else {
$('#questionsTable tbody').append(Utils.processTemplate("#sectionRowTemplate tbody", data));
}
Below is my HTML and jQuery code. jQuery displays the hidden elements, except for the #image4 and #video4 elements, which stay hidden with if I select image or video. All the other elements get displayed correctly.
Any idea why those two won't show?
JS:
$(document).ready(function(){
var fields = jQuery('#image_type');
var select = this.value;
fields.change(function () {
if ($(this).val() == 'image') {
alert($(this).val());
$('#images_pop_up').show();
$('#video1').hide();
$('#video2').hide();
$('#video3').hide();
$('#video4').hide();
$('#image1').show();
$('#image2').show();
$('#image3').show();
$('#image4').show();
$(' #image5').show();
}
else {
$('#images_pop_up').show();
$('#image1').hide();
$('#image2').hide();
$('#image3').hide();
$('#image4').hide();
$('#image5').hide();
$('#video1').show();
$('#video2').show();
$('#video3').show();
$('#video4').show();
$('#image5').show();
}
});
});
HTML:
<div id ="images_pop_up" style="display:none;">
<span id="image1" style="display:none;" ><img src="/uploads/commerce/images/large/easton-163135-wheeled-bag.jpg" border="0" alt="easton-163135-wheeled-bag.jpg" title=" easton-163135-wheeled-bag.jpg " class="productimage"><input type="hidden" name="products_previous_image_lrg" value="easton-163135-wheeled-bag.jpg"><br>Nice bag</span>
<span id ="video1" style="display:none;"></span></td>
<td class="textSmall" valign="top">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<span id="image3" style="display:none;"><input type="hidden" name="products_previous_image_lrg" value="easton-163135-wheeled-bag.jpg"><input type="hidden" name="products_previous_image_lrg_caption" value="Nice bag"></span>
<span id ="video3"><input type="hidden" name="products_previous_video_embed"><input type="hidden" name="products_previous_video_embed_caption"></span>
<td class="textSmall" valign="top"><span id="image4" style="display:none;">New Image File: <input type="text" name="products_image_lrg" value="easton-163135-wheeled-bag.jpg"><br>Image Caption: <input type="text" name="products_image_lrg_caption" value="Nice bag"></span>
<span id ="video4" style="display:none;">Video Embed field: <input type="text" name="products_video_embed"><br>Video Image Caption: <input type="text" name="products_video_embed_caption"></span>
</td>
<td><span id="image5" style="display:none;"> </span></td>
</tr>
<tr>
<td colspan="2">
<div id='div_img_lrg'></div>
</td>
</tr>
</table>
</td>
</div>
What sticks out most to me is that you're copy pasting when you could be putting CSS to work for you by giving them all the same class (or the appropriate groups of elements the same class at least) and then hiding and showing them based on that.
Your bug is probably caused by a slight typo somewhere in the selectors or the place where you're setting the ids in the markup.
try like this
$(document).ready(function () {
var fields = jQuery('#image_type');
var select = this.value;
$('#image_type').change(function () {
if ($(this).val() == 'image') {
alert($(this).val());
$("[id^=image]").show();
$("[id^=video]").hide();
} else {
$("[id^=video]").show();
$("[id^=image]").hide();
}
});
});
I have several start and end dates in my system, in some cases I have several start and end dates in a screen. All of them are grouped in sets of two and have the same behaviour: the start date can't be greater than the end date and the difference between them can't be greater than a user-entered input.
I know that i have to create two methods, one for validating the first case and other for the second case. The problem is that I don't know how to reference the fields, for example:
// A custom method for validating the date range.
$.validator.addMethod("dateRange", function() {
var startDate = $("#startDate").val();
var endDate = $("#endDate").val();
return isDate(startDate) && isDate(endDate) ? Date.parse(startDate) <= Date.parse(endDate) : true;
});
The problem is: this way I hard-coded the input names. This would work if I had only one set of dates per screen, but when I have more than one this won't work. How do I create a method without hard-coding the IDs of the elements that I want to use so as to use it all around the system?
I've read the online documentation in http://jqueryvalidation.org/jQuery.validator.addMethod/ but does seem to handle my problem and I think using groups wouldn't be enough to handle all elements, I probably would have to copy/paste for each set of dates.
I believe if you help me with one of the cases the second will be resolved using the same logic.
EDIT: As requested, here's the HTML
<table width="95%" id="tabela_interna">
<thead><tr valign="middle"><th colspan="6">Relatório Internações Concierge</th></tr></thead>
<tbody>
<tr valign="middle">
<td width="11%" align="left" class="td_label"><label for="dataInicialSolicitacao">Data Solicitação Inicial</label></td>
<td width="25%" align="left" class="td_dados">
<input type="text" name="filtro.dataInicialSolicitacao" size="12" value="" id="dataInicialSolicitacao" class="data"/>
</td>
<td width="11%" align="left" class="td_label"><label for="dataFinalSolicitacao">Data Solicitação Final</label></td>
<td width="25%" align="left" class="td_dados">
<input type="text" name="filtro.dataFinalSolicitacao" size="12" value="" id="dataFinalSolicitacao" class="data"/>
</td>
</tr>
<tr valign="middle">
<td width="11%" align="left" class="td_label"><label for="dataInicialLiberacao">Data Liberação Inicial</label></td>
<td width="25%" align="left" class="td_dados">
<input type="text" name="filtro.dataInicialLiberacao" size="12" value="" id="dataInicialLiberacao" class="data"/>
</td>
<td width="11%" align="left" class="td_label"><label for="dataFinalLiberacao">Data Liberação Final</label></td>
<td width="25%" align="left" class="td_dados">
<input type="text" name="filtro.dataFinalLiberacao" size="12" value="" id="dataFinalLiberacao" class="data"/>
</td>
</tr>
<tr valign="middle">
<td width="11%" align="left" class="td_label"><label for="dataInicialInternacao">Data Internação Inicial</label></td>
<td width="25%" align="left" class="td_dados">
<input type="text" name="filtro.dataInicialInternacao" size="12" value="" id="dataInicialInternacao" class="data"/>
</td>
<td width="11%" align="left" class="td_label"><label for="dataFinalInternacao">Data Internação Final</label></td>
<td width="25%" align="left" class="td_dados">
<input type="text" name="filtro.dataFinalInternacao" size="12" value="" id="dataFinalInternacao" class="data"/>
</td>
</tr>
</table>
I tend to do this using custom attributes, e.g.:
<input type="text" id="x" data-validate-date="true" data-validate-against="y" value="01/01/2000" />
<input type="text" id="y" value="1/1/2001" />
<input type="text" id="a" data-validate-date="true" data-validate-against="b" value="01/01/2000" />
<input type="text" id="b" value="4/4/2020" />
You can then define your validation rule something like:
$.validator.addMethod("dateRange", function() {
var allValid = true;
var results = [];
var datesToValidate = $("[data-validate-date]");
for(var i = 0; i < datesToValidate.length; i++) {
var d = datesToValidate[i];
var startDate = $(d).val();
var endDateSelector = "#" + $(d).attr("data-validate-against");
var endDate = $(endDateSelector).val();
results[i] = isDate(startDate) && isDate(endDate) && (Date.parse(startDate) <= Date.parse(endDate));
}
for(var j = 0; j < datesToValidate.length; j++) {
if(!(results[j] == true)) {
allValid = false;
}
}
return allValid;
});
I don't know if that's the best way to do it, but I think it could work for you.
I used the approach suggested by Blazemonger and created a method based on equalTo.
$.validator.addMethod("startDateCantBeGreaterThanEndDate", function(value, element, param) {
var target = $(param);
if (this.settings.onfocusout) {
target.unbind(".validate-startDateCantBeGreaterThanEndDate").bind("blur.validate-startDateCantBeGreaterThanEndDate", function() { $(element).valid(); });
}
value > target.val();
});
And used the method the same way equalTo does:
$("form").validate({
rules: {
"filtro.dataInicialSolicitacao": { startDateCantBeGreaterThanEndDate: "#dataFinalSolicitacao" },
},
messages: {
"filtro.dataInicialSolicitacao": { startDateCantBeGreaterThanEndDate: "Type your custom message." },
}
});
SOLVED: SEE "CORRECTED SOLUTION" Area (below)
--------------------------------- ORIGINAL TEXT ---------------------------
I've created a JavaScript toaster popup to show info about an individual row. It works great in FireFox...but it goes down in flames in IE.
...suggestions and help appreciated.
WHAT I THINK IS FAILING:
I think I declared the "Toaster" class wrong and IE isn't doesn't recognize it as an array. As such, when I call "PopUp(clientId)" on the toaster it fails becuase it doesn't traverse the array.
Additionally, FireFox populates the array correctly in the documents "ready" function...but I'm not sure IE is doing so.
Lastly, since I am still new to JavaScript it (obviously) could be HOW I am creating the classes (as well).
WHERE IT FAILS:
The code fails because the value of "target" is null. This variable is null because IE doesn't seem to traverse the Toaster (array).
this.PopUp = function(clientId) {
var target = null;
jQuery.each(this, function() {
// Hide previous
if (jQuery(this)[0].IsUp)
jQuery(this)[0].PopDown();
if (jQuery(this)[0].ClientId == clientId)
target = jQuery(this)[0];
});
// Show current
target.PopUp();
}
THE FULL CODE SET:
Thanks for the help...
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title></title>
<script src="../Includes/JavaScript/jQuery/Core/jquery-1.3.2.js" type="text/javascript"></script>
<style type="text/css">
.toast
{
width: 100%;
position: relative;
}
.toastBorder
{
width: 100%;
position: absolute;
border-radius-topright:.5em;
border-radius-topleft:.5em;
-moz-border-radius-topright:.5em;
-moz-border-radius-topleft:.5em;
-webkit-border-radius-topright:.5em;
-webkit-border-radius-topleft:.5em;
background-color: #FFFFCC;
border: 1px solid #969696;
border-bottom-color: White;
display:none;
height: 0;
bottom: 0;
}
.toastForm
{
display:none;
}
</style>
<script type="text/javascript">
// CLASS DEFINITION:
function Toast(clientId, height, speed) {
// PROPERTIES
this.IsUp = false;
this.IsDown = false;
this.ClientId = clientId;
this.Height = height;
this.Speed = speed;
// METHODS
this.PopUp = function() {
if (this.IsUp) { return; }
this.IsUp = true;
this.IsDown = false;
var speed = this.Speed;
var action = '+=' + this.Height + "px";
// Border
jQuery('#' + this.ClientId).children('div.toastBorder').fadeIn('fast', function() {
jQuery(this).animate({ height: action }, speed, function() {
// Form
jQuery(this).children('div.toastForm').fadeIn('fast');
});
});
}
this.PopDown = function() {
if (this.IsDown) { return; }
this.IsUp = false;
this.IsDown = true;
var speed = this.Speed;
var action = '-=' + this.Height + "px";
// Form
jQuery('#' + this.ClientId).children('div.toastBorder').children('div.toastForm').fadeOut('fast');
// Border
jQuery('#' + this.ClientId + ' div.toastBorder').animate({ height: action }, speed, function() {
jQuery(this).fadeOut('fast');
});
}
}
// CLASS DEFINITION:
function Toaster() {
// PROPERTIES
// METHODS
this.PopUp = function(clientId) {
var target = null;
jQuery.each(this, function() {
// Hide previous
if (jQuery(this)[0].IsUp)
jQuery(this)[0].PopDown();
if (jQuery(this)[0].ClientId == clientId)
target = jQuery(this)[0];
});
// Show current
target.PopUp();
}
this.PopDown = function(clientId) {
jQuery.each(this, function() {
if (jQuery(this)[0].ClientId == clientId)
jQuery(this)[0].PopDown(); // Hide current
});
}
this.Add = function(toast) {
var found = false;
// No duplicates are allowed
jQuery.each(this, function() {
if (jQuery(this)[0].ClientId == toast.ClientId)
found = true;
});
if (!found)
this.push(toast);
}
}
// CLASS DEFINITION: Toaster inheritance
Toaster.prototype = new Array();
var myToaster;
var myToast;
// DOM EVENT: Document.Ready()
jQuery(document).ready(function() {
if (myToaster == null)
myToaster = new Toaster();
myToaster.Add(new Toast("row1", 100, 200));
myToaster.Add(new Toast("row2", 100, 200));
myToaster.Add(new Toast("row3", 100, 200));
myToaster.Add(new Toast("row4", 100, 200));
myToaster.Add(new Toast("row5", 100, 200));
// These BOTH return true in IE...
//alert(myToaster.Items instanceof Array);
//alert(myToaster instanceof Array);
// This is for the button example
if (myToast == null)
myToast = new Toast("row3", 100, 200);
});
</script>
</head>
<body>
<br />
I need help on the following:
<ul>
<li>
This works GREAT in FireFox
</li>
<li>
IE doesn't seem to recognize the Toaster class as being an array.
</li>
</ul>
<div style="width: 300;">
<label style="display:block;color: #660000;">INDIVIDUAL pieces of toast work fine in IE:</label>
<input type="button" value="Down (row 3)" onclick="myToast.PopDown();" />
<input type="button" value="Up (row 3)" onclick="myToast.PopUp();" />
</div>
<br /><br />
<label style="color: #660000">Clicking a row IS SUPPOSED TO toggle a "piece of toast" for that row.</label>
<br /><br />
<table cellpadding="0" cellspacing="0" width="500" style=" border: solid 1px black">
<tr>
<td align="center" style="border-bottom: solid 1px black;">
Header
</td>
<td align="center" style="border-bottom: solid 1px black;">
Header
</td>
<td align="center" style="border-bottom: solid 1px black;">
Header
</td>
<td align="center" style="border-bottom: solid 1px black;">
Header
</td>
<td align="center" style="border-bottom: solid 1px black;">
Header
</td>
</tr>
<tr>
<td>
</td>
<td colspan="3">
<div id="row1" class="toast">
<div class="toastBorder">
<div align="center" class="toastForm">
<br />
Hello
<br /><br /><br /><br /><br />
</div>
</div>
</div>
</td>
<td>
</td>
</tr>
<tr onclick="myToaster.PopUp('row1');">
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
</tr>
<tr>
<td>
</td>
<td colspan="3">
<div id="row2" class="toast">
<div class="toastBorder">
<div align="center" class="toastForm">
<br />
Hello
<br /><br /><br /><br /><br />
</div>
</div>
</div>
</td>
<td>
</td>
</tr>
<tr onclick="myToaster.PopUp('row2');">
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
</tr>
<tr>
<td>
</td>
<td colspan="3">
<div id="row3" class="toast">
<div class="toastBorder">
<div align="center" class="toastForm">
<br />
Hello
<br /><br /><br /><br /><br />
</div>
</div>
</div>
</td>
<td>
</td>
</tr>
<tr onclick="myToaster.PopUp('row3');">
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
</tr>
<tr>
<td>
</td>
<td colspan="3">
<div id="row4" class="toast">
<div class="toastBorder">
<div align="center" class="toastForm">
<br />
Hello
<br /><br /><br /><br /><br />
</div>
</div>
</div>
</td>
<td>
</td>
</tr>
<tr onclick="myToaster.PopUp('row4');">
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
</tr>
<tr>
<td>
</td>
<td colspan="3">
<div id="row5" class="toast">
<div class="toastBorder">
<div align="center" class="toastForm">
<br />
Hello
<br /><br /><br /><br /><br />
</div>
</div>
</div>
</td>
<td>
</td>
</tr>
<tr onclick="myToaster.PopUp('row5');">
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
<td align="center">
Data
</td>
</tr>
</table>
</body>
</html>
HERE IS THE CORRECTED SOLUTION:
// CLASS DEFINITION:
function Toast(clientId, maxHeight, speed) {
// PROPERTIES
this.ClientId = clientId;
this.MaxHeight = maxHeight;
this.Speed = speed;
// METHODS
this.IsUp = function() {
return (jQuery('#' + this.ClientId).children().height() > 0) ? true : false;
}
this.PopUp = function() {
if (this.IsUp()) { return; }
var speed = this.Speed;
var action = '+=' + this.MaxHeight + "px";
// Border
jQuery('#' + this.ClientId).children('div.toastBorder').fadeIn('fast', function() {
jQuery(this).animate({ height: action }, speed, function() {
// Form
jQuery(this).children('div.toastForm').fadeIn('fast');
});
});
this.IsUp(true);
}
this.PopDown = function() {
if (!this.IsUp()) { return; }
var speed = this.Speed;
var action = '-=' + this.MaxHeight + "px";
// Form
jQuery('#' + this.ClientId).children('div.toastBorder').children('div.toastForm').fadeOut('fast');
// Border
jQuery('#' + this.ClientId).children('div.toastBorder').animate({ height: action }, speed, function() {
jQuery(this).fadeOut('fast');
});
this.IsUp(false);
}
}
// CLASS DEFINITION:
function Toaster() {
// PROPERTIES
this.Items = new Array();
// METHODS
this.PopUp = function(clientId) {
var target = null;
jQuery.each(this.Items, function() {
if (jQuery(this)[0].ClientId != clientId) {
if (jQuery(this)[0].IsUp()) {
jQuery(this)[0].PopDown(); // Hide previous
}
}
if (jQuery(this)[0].ClientId == clientId) {
target = jQuery(this)[0];
}
});
if (target != null) {
if (target.IsUp() == false)
target.PopUp();
}
}
this.PopDown = function(clientId) {
jQuery.each(this.Items, function() {
if (jQuery(this)[0].ClientId == clientId)
jQuery(this)[0].PopDown(); // Hide current
});
}
this.Add = function(toast) {
var found = false;
// No duplicates are allowed
jQuery.each(this.Items, function() {
if (jQuery(this.Items)[0].ClientId == toast.ClientId)
found = true;
});
if (!found)
this.Items.push(toast);
}
}
var myToaster;
var myToast;
// DOM EVENT: Document.Ready()
$j(document).ready(function() {
if (myToaster == null)
myToaster = new Toaster();
myToaster.Add(new Toast("row1", 125, 200));
myToaster.Add(new Toast("row2", 125, 200));
myToaster.Add(new Toast("row3", 125, 200));
myToaster.Add(new Toast("row4", 125, 200));
myToaster.Add(new Toast("row5", 125, 200));
});
</script>
The attempt to "subclass" Array by using it as the prototype object for your "Toaster" class is not going to work in IE, for whatever reason. If you debug the "Add" method, you'll notice that calls to "push" don't seem to fail, but they also don't change the length of the Toaster.
Trying to make Javascript act like a nice polite object-oriented language is fraught with peril, particularly when you try and treat the native types (like Array) as if they're implemented in Javascript too.
I'd just keep an array around as part of "Toaster" someplace.