ModalPopupExtender gets stuck in Show when same TargetControlID is activated - modalpopupextender

I have a ModalPopupExtender tied to a RadListBox so that when an item is selected from the list box, I need a "Please Wait" message while the page behind loads the data into RadCharts. The Modal does Hide when the loading is completed. The problem I'm having is if the same list item is selected again, the Modal popup shows again, but never goes away. I've tried just about everything, but the click/selection of a list item in the RadListBox immediately shows the Modal and I can't seem to find a way to do item checking to see if its the same item, then to do nothing.
Here is my Panel and Modal code (ASPX)
<asp:Panel ID="pnlProgress" runat="server" Height="50px" Width="50px" >
<div>
<div class="popupbody">
<table width="50%">
<tr>
<td align="center">
<asp:Image ID="imgProgress" runat="server" ImageUrl="~/_images/ajax-loader.gif" />
<br />
<br />
<asp:Label ID="lblLoading" runat="server" Text='Please wait...'
Font-Bold="true"></asp:Label>
</td>
</tr>
</table>
</div>
</div>
</asp:Panel>
<ajaxToolKit:ModalPopupExtender ID="mpeProgress" runat="server" TargetControlID="lboxTestedMachines" PopupDragHandleControlID="pnlProgress" `enter code here`
X="1000" Y="500" PopupControlID="pnlProgress" BackgroundCssClass="modalBackground" RepositionMode="RepositionOnWindowResize" BehaviorID="lboxTestedMachines">
</ajaxToolKit:ModalPopupExtender>
And here is my ASPX.CS code
protected void lboxTestedMachines_SelectedIndexChanged(object sender, EventArgs e)
{
int iResultID = Convert.ToInt32(lboxTestedMachines.SelectedValue);
if (tbl_charts.Style.Value != "display:normal")
tbl_charts.Style.Value = "display:normal";
GetMachineName(iResultID);
RdListView_Chart.DataSource = LoadCassetteForFoodChart(iResultID);
GetApprovalRejectionStatus(iResultID);
}

The RadListBox has an internal logic on item click to determine if the item was already selected. If it was, it would not trigger the OnClientSelectedIndexChanging event, hence no postback on clicking a selected item.
The ModalPopupBehavior on the other hand reacts to any click event inside TargetControlID control's element. Here are some code snippets obtained using the browser's DevTools (search for Sys.Extended.UI.ModalPopupBehavior.prototype.initialize by following steps from Get IntelliSense for the client-side object)
initialize: function() {
Sys.Extended.UI.ModalPopupBehavior.callBaseMethod(this, "initialize"),
this._isIE6 = Sys.Browser.agent == Sys.Browser.InternetExplorer && Sys.Browser.version < 7,
this._popupDragHandleControlID && (this._dragHandleElement = $get(this._popupDragHandleControlID)),
this._popupElement = $get(this._popupControlID),
this._createDomElements(),
this._showHandler = Function.createDelegate(this, this._onShow),
$addHandler(this.get_element(), "click", this._showHandler),
this._okControlID && (this._okHandler = Function.createDelegate(this, this._onOk),
$addHandler($get(this._okControlID), "click", this._okHandler)),
this._cancelControlID && (this._cancelHandler = Function.createDelegate(this, this._onCancel),
$addHandler($get(this._cancelControlID), "click", this._cancelHandler)),
this._scrollHandler = Function.createDelegate(this, this._onLayout),
this._resizeHandler = Function.createDelegate(this, this._onLayout),
this.registerPartialUpdateEvents(),
this._resetAnimationsTarget(),
this._onHiding.get_animation() && (this._hidingAnimationEndedHandler = Function.createDelegate(this, function () {
this._isAnimationJustEnded = !0,
this.hide()
}),
this._onHiding.get_animation().add_ended(this._hidingAnimationEndedHandler)),
this._onShowing.get_animation() && (this._showingAnimationEndedHandler = Function.createDelegate(this, function () {
this._isAnimationJustEnded = !0,
this.show()
}),
this._onShowing.get_animation().add_ended(this._showingAnimationEndedHandler))
},
_onShow: function(e) {
if (!this.get_element().disabled)
return this.show(),
e.preventDefault(),
!1
},
Solution 1: Subscribe to the Showing event of the ModalPopupBehavior and allow it to show only when you set a flag from the OnClientSelectedIndexChanging event. The example below stores the flag in the RadListBox client-side object as an expando property:
<telerik:RadCodeBlock runat="server" ID="rdbScripts">
<script type='text/javascript'>
function pageLoadHandler() {
var modalPopupExtenderClientObject = $find("<%= mpeProgress.ClientID %>")
modalPopupExtenderClientObject.add_showing(function (sender, args) {
// "sender" argument represents the Modal popup control client-side object
// sender.get_element() returns the DOM element of the RadListBox
// sender.get_element().control return the client-side object of the RadListBox where we stored the expando property __allowModalPopupShow
if (sender.get_element().control.__allowModalPopupShow !== true) {
args.set_cancel(true);
}
})
}
function OnClientSelectedIndexChanging(sender, args) {
// sender in this context is the RadListBox client-side object
sender.__allowModalPopupShow = true;
}
Sys.Application.add_load(pageLoadHandler);
</script>
</telerik:RadCodeBlock>
Solution 2: Use RadAjaxLoading panel and show it programmatically in OnClientSelectedIndexChanging:
https://docs.telerik.com/devtools/aspnet-ajax/controls/ajaxloadingpanel/how-to/show-and-hide-ajaxloadingpanel-explicitly
https://demos.telerik.com/aspnet-ajax/ajaxloadingpanel/functionality/transparency/defaultcs.aspx

Related

How to access newly created DOM elements in JS? (I have used appendChild)

I am making a to do list. Each list item includes a remove button when created.
But I cannot access these remove buttons in my script, because it is not included in my DOM, although I used '.appendChild'. Can anyone help?
const buttonSubmit = document.querySelector('#button-submit');
const form = document.querySelector('form');
const icons = document.querySelector('#icons');
let toDoList = document.querySelector('#todolist');
const input = document.querySelector('#formtext');
form.addEventListener('submit', (e) => {
e.preventDefault();
const newListItem = document.createElement('li');
newListItem.innerHTML = '<span>' + input.value + '</span>' +
'<span id="icons">' +
'<button id="check" class="buttonlist">' + '<img src="checked.png" alt="">' + '</button>' +
'<button id="remove" class="buttonlist">' + '<img src="remove.png" alt="">' + '</button>' +
'<button id="edit" class="buttonlist">' + '<img src="edit.png" alt="">' + '</button>' + '</span>';
toDoList.appendChild(newListItem);
form.reset();
})
const buttonCheck = document.querySelector('#check');
const buttonEdit = document.querySelector('#edit');
const buttonRemove = document.getElementById('remove');
buttonRemove.addEventListener('click', function() {
alert('remove list item');
})
<div class="container-box">
<h1>To Do List</h1>
<br>
<form action="">
<input type="text" id="formtext" name="formtext">
<button id="button-submit">Add Item</button>
</form>
<br><br><br><br>
<!-- Dynamic list here -->
<ul id="todolist"> </ul>
</div>
Problems
ids must be unique, every time you add a task to the list -- after the first one everything is invalid HTML. When directed to an id the browser will find the first id then stop and ignore the duplicate ids. Use class and/or name attributes for any replicated tags.
The reason why the remove button doesn't work is because the reference to the button was defined when it didn't exist.
Figure I
// After page is loaded...
const buttonRemove = document.getElementById('remove');
// Console will tell you buttonRemove is null
// User has not entered any data nor has user clicked the add button
Moreover, even if that was fixed by referencing the button after it was created, binding it as shown on Figure II will only work for the first button only.
Figure II
buttonRemove.addEventListener('click', function() {
alert('remove list item'); // Don't use alert() use console.log()
})
Solution
Reference tags after they are created. In the OP (Original Post), the contents of the <li> is rendered htmlString which makes referencing newly created tags problematic plus binding to dynamically created tags individually should be avoided if it's feasible and practical in which in most cases it is.
To handle events for an unknown amount of dynamically created tags, bind the event to a static ancestor tag, which in the OP is <ul> or any of it's parent tags (even <body>, document, and window but it's best to be as close as possible). Then make it so the event handler controls which tags respond and how. See Appendix located at the very end of this answer for more details.
There are two examples:
Example A - revised OP code
Example B - a todo list using HTMLFormElement interface, see Appendix
Both examples have commented step-by-step details
Example A
// Reference <form>, <ul>, and <input>
const form = document.querySelector('form');
const list = document.querySelector('ul');
const input = document.querySelector('#text');
// Bind <form> to submit event
form.addEventListener('submit', (e) => {
// Stop default behavior of <form> during submit ecent
e.preventDefault();
// Create <li> and <output>
const item = document.createElement('li');
const out = document.createElement('output');
// Assign value of <input> to the value of <output>
out.value = input.value;
// Add <output> to <li> -- <li> to <ul>
item.append(out);
list.append(item);
/*
Run a for loop 3 times -- on each iteration...
...create an <input> and assign type as "button"...
...buttons [name] and [value] is determined by current index...
...add button to <li>
*/
for (let i = 0; i < 3; i++) {
let btn = document.createElement('input');
btn.type = 'button';
let cmd = i === 0 ? 'done' : i === 1 ? 'edit' : i === 2 ? 'remove' : false;
btn.name = cmd;
btn.value = cmd;
item.append(btn);
}
// Reset <form>
form.reset();
});
// Bind <ul> to click event
list.addEventListener('click', manageList);
// Event handler always passes event object by default
function manageList(e) {
// Reference the tag user clicked
const clk = e.target;
// If user clicked a remove button remove it's parent tag
if (clk.name === 'remove') {
clk.parentElement.remove();
}
if (clk.name === 'edit') {
console.log('EDIT');
}
if (clk.name === 'done') {
console.log('DONE');
}
}
li {
display: flex;
align-items: center
}
[type='button'] {
text-transform: capitalize
}
<form>
<input id="text" name="text" type="text">
<button>Add Item</button>
</form>
<br>
<ul></ul>
Example B
// Bind <form> to click event
document.forms.todo.onclick = taskList;
// Event handler akways passes the event object
function taskList(e) {
// Reference the tag user clicked
const clk = e.target;
// Reference all form controls
const IO = this.elements;
/*
If the user clicked the add button...
...reference the <ul>...
...create <li> and <output>...
...add text from <input> to <output>...
...add <output> to <li>...
...Run a for loop 3 times -- on each iteration...
...create an <button> and assign type as "button"...
...buttons [name] and text is determined by current index...
...add button to <li>...
...add <li> to <ul>...
...clear <input>
*/
if (clk.name == 'add') {
const list = IO.list.firstElementChild;
const item = document.createElement('li');
const text = document.createElement('output');
text.value = IO.data.value;
item.append(text);
for (let i = 0; i < 3; i++) {
let btn = document.createElement('button');
btn.type = 'button';
let cmd = i === 0 ? 'done' : i === 1 ? 'edit' : i === 2 ? 'remove' : false;
btn.name = cmd;
btn.textContent = cmd;
item.append(btn);
}
list.append(item);
IO.data.value = '';
}
/*
If the user clicked a remove button...
...find the <li> ancestor of remove button and remove
it thereby removing the <output> and itself as well
*/
if (clk.name === 'remove') {
clk.closest('li').remove();
}
if (clk.name === 'done') {
console.log('DONE');
}
if (clk.name === 'edit') {
console.log('EDIT');
}
}
<form id='todo'>
<input id='data' required><button name='add' type='button'>Add</button>
<fieldset id='list'>
<ul></ul>
</fieldset>
</form>
Appendix
Events
Event delegation
HTMLFormElement
HTMLFormControlsCollection
Form Controls

React onClick keeps triggering

When I trigger the onClick even the event keeps triggering for about 1000+ times. I can't seem to figure where this is coming from. I have changed the onClick to an onMouseover to see if it keeps triggering but then the event only triggers once.
I'm using : react 0.13.3
Any idea's?
var React = require('react');
var AppActions = require('../../actions/app-actions.js');
var FileAmount = React.createClass({
getInitialState: function() {
return {
amount : this.props.amount,
config : this.props.config
};
},
handleClick: function(e){
var name = e.target.name;
if(name === 'decrease'){
if(this.state.amount > 1){
this.setState({
amount : (this.state.amount - 1)
});
AppActions.updateAmount(this.props.index, (this.state.amount - 1))
}
}else{
this.setState({
amount : (this.state.amount + 1)
});
AppActions.updateAmount(this.props.index, (this.state.amount + 1))
}
},
handleChange: function(e){
var amount = e.target.value;
this.setState({
amount : amount
});
AppActions.updateAmount(this.props.index, amount)
},
render: function() {
var config = this.state.config
return (
<div className="file-amount">
<span className="file-amount-text"> {config.filelist_quantity}: {this.state.amount} {config.filelist_pieces}</span>
<div className="file-amount-fields">
<i className="file-amount-decrease icon" name="decrease" onClick={this.handleClick} />
<input className="file-amount-input" type="number" value={this.state.amount} onChange={this.handleChange} />
<i className="file-amount-increase icon" name="increase" onClick={this.handleClick} />
</div>
</div>
);
}
});
module.exports = FileAmount;
I left a comment on the original post, but on second inspection, it looks quite possible that you pass down props.amount from a Flux Store. If that is the case you're creating an infinite loop.
handleClick increments state.amount, then after the AppAction is called, the Store updates the component with props.amount, then the onChange fires because it is tied to state.amount and then onChange changes state.amount and changes props.amount when it calls AppActions.updateAmount.
Every time props or state are updated, React will call the render() method. If there is any way that props or state get updated while the render() executes, then you are likely going to run into an infinite loop.
Perhaps adding a e.preventDefault(); to your handleClick method will stop this loop from being started.
I removed the added javascript for the browser-sync proxy settings. That somehow screwed around with my react.

Mvvm with knockout : array binding and changing inner objects state

I have an array in my View Model. Items of this array are objects of Person that has two properties. when I bind this to a template it's okay. but when I change the state of one of the properties it does not reflect in UI.
what did I do wrong ?
<script type="text/html" id="person-template">
<p>Name: <span data-bind="text: name"></span></p>
<p>
Is On Facebook ?
<input type="checkbox" data-bind="checked: IsOnFacebook" />
</p>
</script>
<script type="text/javascript">
var ppl = [
{ name: 'Pouyan', IsOnFacebook: ko.observable(true) },
{ name: 'Reza', IsOnFacebook: ko.observable(false) }
];
function MyViewModel() {
this.people = ko.observableArray(ppl),
this.toggle = function () {
for (var i = 0; i < ppl.length; i++) {
ppl[i].IsOnFacebook = false;
}
}
}
ko.applyBindings(new MyViewModel());
</script>
when I press the button I want to make changes in People.IsOnFacebook property. the changes will be made successfully but the UI does not show.
You should call it like a function. Like:
ppl[i].IsOnFacebook(false);
This because the ko.observable() returns a function. It's not a property you call anymore but a function call. So in the background they will update your UI. To retreive a property that is observable. You should also use the function call.
Please see this tutorial: http://learn.knockoutjs.com/#/?tutorial=intro

Google Autocomplete - enter to select

I have Google Autocomplete set up for a text field of an HTML form, and it's working perfectly.
However, when the list of suggestions appear, and you use the arrows to scroll and select using enter, it submits the form, though there are still boxes to fill in. If you click to select a suggestion it works fine, but pressing enter submits.
How can I control this? How can I stop enter from submitting the form, and instead be the selection of a suggestion from autocomplete?
Thanks!
{S}
You can use preventDefault to stop the form being submitted when enter is hit, I used something like this:
var input = document.getElementById('inputId');
google.maps.event.addDomListener(input, 'keydown', function(event) {
if (event.keyCode === 13) {
event.preventDefault();
}
});
Using the Google events handling seems like the proper solution but it's not working for me. This jQuery solution is working for me:
$('#inputId').keydown(function (e) {
if (e.which == 13 && $('.pac-container:visible').length) return false;
});
.pac-container is the div that holds the Autocomplete matches. The idea is that when the matches are visible, the Enter key will just choose the active match. But when the matches are hidden (i.e. a place has been chosen) it will submit the form.
I've amalgamated the first two answers from #sren and #mmalone to produce this:
var input= document.getElementById('inputId');
google.maps.event.addDomListener(input, 'keydown', function(e) {
if (e.keyCode == 13 && $('.pac-container:visible').length) {
e.preventDefault();
}
});
works perfectly on the page. prevents the form from being submitted when the suggestion container (.pac-container) is visible. So now, an option from the autocomplete dropdown is selected when the users presses the enter key, and they have to press it again to submit the form.
My main reason for using this workaround is because I found that if the form is sent as soon as an option is selected, via the enter key, the latitude and longitude values were not being passed fast enough into their hidden form elements.
All credit to the original answers.
This one worked for me:
google.maps.event.addDomListener(input, 'keydown', e => {
// If it's Enter
if (e.keyCode === 13) {
// Select all Google's dropdown DOM nodes (can be multiple)
const googleDOMNodes = document.getElementsByClassName('pac-container');
// Check if any of them are visible (using ES6 here for conciseness)
const googleDOMNodeIsVisible = (
Array.from(googleDOMNodes).some(node => node.offsetParent !== null)
);
// If one is visible - preventDefault
if (googleDOMNodeIsVisible) e.preventDefault();
}
});
Can be easily converted from ES6 to any browser-compatible code.
The problem I had with #sren's answer was that it blocks the submit event always. I liked #mmalone's answer but it behaved randomly, as in sometimes when I hit ENTER to select the location, the handler ran after the container is hidden. So, here's what I ended up doing
var location_being_changed,
input = document.getElementById("js-my-input"),
autocomplete = new google.maps.places.Autocomplete(input),
onPlaceChange = function () {
location_being_changed = false;
};
google.maps.event.addListener( this.autocomplete,
'place_changed',
onPlaceChange );
google.maps.event.addDomListener(input, 'keydown', function (e) {
if (e.keyCode === 13) {
if (location_being_changed) {
e.preventDefault();
e.stopPropagation();
}
} else {
// means the user is probably typing
location_being_changed = true;
}
});
// Form Submit Handler
$('.js-my-form').on('submit', function (e) {
e.preventDefault();
$('.js-display').text("Yay form got submitted");
});
<p class="js-display"></p>
<form class="js-my-form">
<input type="text" id="js-my-input" />
<button type="submit">Submit</button>
</form>
<!-- External Libraries -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//maps.googleapis.com/maps/api/js?sensor=false&libraries=places"></script>
The flag ensures that if the location is being changed & user hits enter, the event is blocked. Eventually the flag is set to false by google map's place_changed event, which then allows the form to be submitted on hitting the enter key.
Here's a simple code that worked well for me (uses no jquery).
const googleAutcompleteField = this.renderer.selectRootElement(this.elem.nativeElement);
this.selectOnEnter(googleAutcompleteField);
This piece of code, to follow the code above, is used to implement google maps autocomplete (with or without the Enter key functionality sought in this question):
this.autocomplete = new google.maps.places.Autocomplete(googleAutcompleteField, this.googleMapsOptions);
this.autocomplete.setFields(['address_component', 'formatted_address', 'geometry']);
this.autocomplete.addListener('place_changed', () => {
this.zone.run(() => {
this.googleMapsData.emit([this.autocomplete.getPlace()]);
})
})
selectOnEnter (called above in the first piece of code) defined:
selectOnEnter(inputField) {
inputField.addEventListener("keydown", (event) => {
const selectedItem = document.getElementsByClassName('pac-item-selected');
if (event.key == "Enter" && selectedItem.length != 0) {
event.preventDefault();
}
})
}
This code makes the google maps autocomplete field select whichever item user selects with the down arrow keypress. Once user selects an option with a press of the Enter key, nothing happens. User has to press Enter again to trigger onSubmit() or other command
You can do it in vanilla :
element.addEventListener('keydown', function(e) {
const gPlaceChoices = document.querySelector('.pac-container')
// No choices element ?
if (null === gPlaceChoices) {
return
}
// Get choices visivility
let visibility = window.getComputedStyle(gPlaceChoices).display
// In this case, enter key will do nothing
if ('none' !== visibility && e.keyCode === 13) {
e.preventDefault();
}
})
I tweaked Alex's code, because it broke in the browser. This works perfect for me:
google.maps.event.addDomListener(
document.getElementById('YOUR_ELEMENT_ID'),
'keydown',
function(e) {
// If it's Enter
if (e.keyCode === 13) {
// Select all Google's dropdown DOM nodes (can be multiple)
const googleDOMNodes = document.getElementsByClassName('pac-container');
//If multiple nodes, prevent form submit.
if (googleDOMNodes.length > 0){
e.preventDefault();
}
//Remove Google's drop down elements, so that future form submit requests work.
removeElementsByClass('pac-container');
}
}
);
function removeElementsByClass(className){
var elements = document.getElementsByClassName(className);
while(elements.length > 0){
elements[0].parentNode.removeChild(elements[0]);
}
}
I've tried the above short answers but they didn't work for me, and the long answers I didn't want to try them, so I've created the following code which worked pretty well for me. See Demo
Suppose this is your form:
<form action="" method="">
<input type="text" name="place" id="google-places-searchbox" placeholder="Enter place name"><br><br>
<input type="text" name="field-1" placeholder="Field 1"><br><br>
<input type="text" name="field-2" placeholder="Field 2"><br><br>
<button type="submit">Submit</button>
</form>
Then the following javascript code will solve the problem:
var placesSearchbox = $("#google-places-searchbox");
placesSearchbox.on("focus blur", function() {
$(this).closest("form").toggleClass('prevent_submit');
});
placesSearchbox.closest("form").on("submit", function(e) {
if (placesSearchbox.closest("form").hasClass('prevent_submit')) {
e.preventDefault();
return false;
}
});
And here is how the full code looks like in the HTML page (Note that you need to replace the YOUR_API_KEY with your google api key):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Prevent form submission when choosing a place from google places autocomplete searchbox</title>
</head>
<body>
<form action="" method="">
<input type="text" name="place" id="google-places-searchbox" placeholder="Enter place name"><br><br>
<input type="text" name="field-1" placeholder="Field 1"><br><br>
<input type="text" name="field-2" placeholder="Field 2"><br><br>
<button type="submit">Submit</button>
</form>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<!-- Google Maps -->
<!-- Note that you need to replace the next YOUR_API_KEY with your api key -->
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"
async defer></script>
<script>
var input = document.getElementById("google-places-searchbox");
var searchBox = new google.maps.places.SearchBox(input);
var placesSearchbox = $("#google-places-searchbox");
placesSearchbox.on("focus blur", function() {
$(this).closest("form").toggleClass('prevent_submit');
});
placesSearchbox.closest("form").on("submit", function(e) {
if (placesSearchbox.closest("form").hasClass('prevent_submit')) {
e.preventDefault();
return false;
}
});
</script>
</body>
</html>
$("#myinput").on("keydown", function(e) {
if (e.which == 13) {
if($(".pac-item").length>0)
{
$(".pac-item-selected").trigger("click");
}
}
Use $('.pac-item:first').trigger('click'); if you want to select first result

Removing form validation causes form not to submit?

I've removed pretty much all .js references in my Magento theme. Specifically I've removed the onclick from the add to cart button.
in template/catalog/product/view/addtocart.phtml I've removed onclick="productAddToCartForm.submit(this)
in template/catalog/product/view/view.phtml I removed this block of code...
<script type="text/javascript">
//<![CDATA[
var productAddToCartForm = new VarienForm('product_addtocart_form');
productAddToCartForm.submit = function(button, url) {
if (this.validator.validate()) {
var form = this.form;
var oldUrl = form.action;
if (url) {
form.action = url;
}
var e = null;
try {
this.form.submit();
} catch (e) {
}
this.form.action = oldUrl;
if (e) {
throw e;
}
if (button && button != 'undefined') {
button.disabled = true;
}
}
}.bind(productAddToCartForm);
productAddToCartForm.submitLight = function(button, url){
if(this.validator) {
var nv = Validation.methods;
delete Validation.methods['required-entry'];
delete Validation.methods['validate-one-required'];
delete Validation.methods['validate-one-required-by-name'];
if (this.validator.validate()) {
if (url) {
this.form.action = url;
}
this.form.submit();
}
Object.extend(Validation.methods, nv);
}
}.bind(productAddToCartForm);
//]]>
</script>
However, now when I submit the form I get nothing.
I figured to change the add to cart <button> to a proper submit. So I changed this....
<button type="button" title="<?php echo $buttonTitle ?>" class="button btn-cart"><span><span><?php echo $buttonTitle ?></span></span></button>
to this ...
<input type="submit" value="<?php echo $buttonTitle ?>" />
When I do that, the form submits but I get a "Page Not Found", the URL it takes me to looks like this /checkout/cart/add/uenc/aHR0cDovLzcwLjMyLjc0LjQ2L3J0bF9tYWdlbnRvL2luZGV4LnBocC9jYXRhbG9nL3Byb2R1Y3Qvdmlldy9pZC8xNQ,,/product/15/
Is it not possible to submit a form the old fashioned way in Magento without javascript? If it is, can you give some pointers?
My plan was to hook up my own jQuery validation (which is quite simple, I just need to validate that the qty field has length) and ditch some of the ridiculousness of the code above.
I don't know how and I don't know why, but when I disable "Use Web Server Rewrites" it works with the standard submit button.