Post dropdownlistfor model binding without reloading page - javascript

I have a "dynamic" page which contains a dropdownlistfor. When I select a value from the dropdown, the page, without redirecting, hides the old div which contained the old dropdown, and displays a new div (using JS .show() function) with a new dropdown that pulls data based on the value of the old dropdown.
My issue is that I don't know how to POST the value of the first dropdown to it's model without redirecting or reloading the page. I have tried this:
$('#binRange_start_form').submit(function(event) {
event.preventDefault();
$(this).submit();
});
Which doesn't call the setter function of my field in my model:
private String _BinRangeSelection;
public String BinRangeSelection
{
get
{
return _BinRangeSelection;
}
set
{
System.Diagnostics.Debug.WriteLine("testing");
string[] rangeSplit = Regex.Split(value, " - ");
foreach (IdentifiBINConfiguration ibc in IdentifiBINConfigs)
{
if (ibc.LowerRange == rangeSplit[0] && ibc.UpperRange == rangeSplit[1])
{
IdentifiBINConfiguration = ibc;
}
}
_BinRangeSelection = value;
}
}
And it also reloads the page.

Related

Multiple Javascript Event Listener Issues

Background info: I'm using WooCommerce and Gravity Forms, and trying to make it so the Add to Cart button is inactive according to two conditions - either there are no attendees registered, or the date hasn't been selected from the product variation dropdown. The user should only be able to move forward if both sections are completed.
The Gravity Forms component of this has a popup module to sign up those attendees, but the summary is displayed outside the module and on the main product page. The class .gpnf-no-entries lives on the "outside" of the Gravity Forms module, since it's always visible on the page. .gpnf-nested-entries and .gpnf-row-actions are also outside the module, but rely on information from within the module. .tingle-btn is a class used on multiple buttons inside the module - to add an attendee, cancel editing, or delete that attendee (unsure if I need a loop on here - alerts were working without one, and it seems like there's something else causing issues regardless).
Issues: It was working at one point, but only after the second click (anywhere on the page). There's also a second issue - on this form, if you've added an attendee but not added the product to the cart, the page retains any info you've put in. So what happens is, if you refresh the page and have old attendee info already there, the Add to Cart never gets clickable after selecting a date, even though both areas are filled out.
Screenshots:
I'm still somewhat of a beginner here so it's quite possibly something silly.
<script>
var modalButtons = document.querySelectorAll('.tingle-btn');
var noEntries = document.querySelector('.gform_body .gpnf-no-entries');
var entryField = document.querySelectorAll(".gpnf-nested-entries .entry-field[style='display: block;']");
var nestedEntriesDelete = document.querySelector('.gpnf-row-actions .delete');
var addToCart = document.querySelector('.single_add_to_cart_button');
var wcVariation = document.querySelector('.woocommerce-variation-add-to-cart');
var selectCheck = document.querySelector('#select-date-option');
//When date selection dropdown is changed, check value and check for "no entries" message
document.addEventListener('change', function (event) {
if (!event.target.matches('selectCheck')) {
if ((noEntries.style.display !== 'none') || (selectCheck.value === '')) {
addToCart.classList.add('disabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-disabled');
}
else {
addToCart.classList.remove('disabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-disabled');
}
}
}, false);
// When attendee is deleted, check to see if there are any entry fields left
document.addEventListener('click', function (event) {
if (!event.target.matches('nestedEntriesDelete')) {
if (entryField.length <= 3) {
addToCart.classList.add('disabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-disabled');
}
}
}, false);
// Check for "no entries" and no date selection value when buttons to add or remove attendees are clicked
document.addEventListener('click', function (event) {
if (!event.target.matches('modalButtons')) {
if ((noEntries.style.display !== 'none') || (selectCheck.value === '')) {
addToCart.classList.add('disabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-disabled');
}
else {
addToCart.classList.remove('disabled');
wcVariation.classList.add('woocommerce-variation-add-to-cart-enabled');
wcVariation.classList.remove('woocommerce-variation-add-to-cart-disabled');
}
}
}, false);
</script>
I ended up doing this a much simpler way by adding classes:
<script>
var noEntries = document.querySelector('.gform_body .gpnf-no-entries');
var entriesContainer = document.querySelector('.gpnf-nested-entries-container');
var addToCart = document.querySelector('.single_add_to_cart_button');
//When page is fully loaded, check for cached entries
window.addEventListener('load', function () {
//if there are entries, show the add to cart button
if (noEntries.style.display === 'none'){
entriesContainer.classList.add('has-entries');
addToCart.classList.add('do-add');
addToCart.classList.remove('dont-add');
}
//if there are no entries, disable the add to cart button
else if (noEntries.style.display === ''){
entriesContainer.classList.remove('has-entries');
addToCart.classList.add('dont-add');
addToCart.classList.remove('do-add');
}
//if the form isn't present, don't do any of this
else if (noEntries = 'null'){
//do nothing
}
});
//When the container with the form and the entries is clicked, check for entries
document.addEventListener('click', function (event) {
if (!event.target.matches('#gform_wrapper_41')) {
setInterval(function() {
//if an entry is added, show the add to cart button
if (noEntries.style.display === 'none'){
entriesContainer.classList.add('has-entries');
addToCart.classList.add('do-add');
addToCart.classList.remove('dont-add');
}
//if all entries are removed, disable the add to cart button
else if (noEntries.style.display === ''){
entriesContainer.classList.remove('has-entries');
addToCart.classList.add('dont-add');
addToCart.classList.remove('do-add');
}
},2000);
}
}, false);
</script>

Keep value after submit form

I have this category checkbox where if I select certain values it will display div size but also in the same time when I select the checkbox it will submit the form. The problem is if I add this.form.submit() , the code below won't work and the form won't submit the value, but if I don't add it, the code will work.
How do I display div size and submit the form at the same time?
function getIds(checkboxName) {
let checkBoxes = document.getElementsByName(checkboxName);
let ids = Array.prototype.slice.call(checkBoxes)
.filter(ch => ch.checked==true)
.map(ch => ch.value);
return ids;
}
$(".category").on('change', function() {
this.form.submit();
let catIds = getIds("category[]");
$.each(catIds, function(index, value){
if (value == '1' || value == '2') {
$("#size").show();
} else if (value == '3') {
$("#size").hide();
}
});
});
This sounds like a racing problem. The form gets put into a different thread by the browser and gets handled first before the rest of the javascript is able to finish.
A quick (but dirty) hotfix for me is usually to use the setTimeout() method.
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout
That way the javascript can work it's magic and afterwards the form gets submitted.

How to filter data based on new and old data

I am new in angular. I have created an inline editable table that can perform CRUD operation inline.
The row which I am creating, I made its id with starting key "a" like this
addNew(): void {
this.data.push({
id: "a" + this.newFieldCounter++,
isEditable: true,
});
}
But user click on add button and when he want to cancel the operation, it should remove that new editable row, for that I have written like this:
cancel(data): void {
this.data = this.data.filter((x) => !(x.id === data.id));
data.isEditable = !data.isEditable;
}
The cancel button working fine for new rows, but when I am clicking on the edit button of the existing record and when I am clicking on the cancel button, that existing record is also getting removed from the table. :(
Is there any way to do it?
Can you try this?
addNew(): void {
this.data.push({
id: "a" + this.newFieldCounter++,
isEditable: true,
isNew: true //for old entries it will be false or undefined
});
}
cancel(data): void {
this.data = this.data.filter((x) => x.id !== data.id && !x.isNew);
data.isEditable = !data.isEditable;
}
Updated
Store in an auxiliar obj the old data, and use a variable to know if is new or nor
onEdit(data)
{
this.isNew=false;
this.oldData={...data} //make a copy using spread operator
...
}
onAdd()
{
this.isNew=true;
...
}
In cancel you can pass the index of the data
<i .... (click)="cancel(tableData,i)"></i>
and
cancel(data,index)
{
if (this.isNew) //<--use the variable
this.data = this.data.filter((x) => !(x.id === data.id));
else
this.tableData[index] ={...this.oldData}
data.isEditable = !data.isEditable;
}
The simplest solution would be, to give new entries a flag, that they are new. So when cancelling the editing, only those entries will be filtered out, that are new.
Therefore you could add (blur)="removeNewFlag(data)" or something like this to remove the flag on submission of your input.
You probably run into an issue, since clicking on the cancel button triggeres the blur event as well. So you can either delay the removeNewFlag method or you can change your code to only submit the input with a button (like the paperplane in messengers).
Check out this demo

Getting default value of radio button upon page load using jQuery

I have two radio buttons whom I set to default (first selected value radio button is the default one upon load) like following:
var listing_type;
var shipping_location;
$(":radio[name='type'][value='1']").attr('checked', 'checked');
$(":radio[name='shipping'][value='1']").attr('checked', 'checked');
When the user clicks on some of the values from radio buttons, the values are caught like following:
$('input:radio[name=type]').click(function () {
listing_type = $(this).val();
});
$('input:radio[name=shipping]').click(function () {
shipping_location = $(this).val();
});
This 2nd part of the code works just fine, when the user clicks on some of the radio buttons, values are passed into my MVC Action just correctly.
However, I'm unable to catch the value if the user doesn't clicks anything on the radio buttons (i.e. leaves them as default as they are upon page load) and clicks "Search" Button...
The values in my MVC Action are always null for some reason, even though they aren't supposed to be. Here is how I'm passing the values and the here is the C# code from the Action:
$.post("/Search/Index", { keywords: $('.txtSearch').val(), type: /* listing_type */ <=> $('input[name=type]:checked').val(), location: $('input[name=shipping]:checked').val() <=> /*shipping_location*/ }, StartLoading())
.done(function (data) {
StopLoading();
var brands = $('<table />').append(data).find('#tableProducts').html();
$('#tableProducts').html(brands);
$('#tableProducts thead').show();
});
}
And this is the Action:
public ActionResult Index(string keywords, string type, string location)
{
// If the user doesn't interacts with the radio buttons and just enters the search term (ie. keywords) the type and location variables are null).
if ((keywords != null && keywords != "") && (type != null && type != "") && (location != null && location!=""))
{
// do something here....
}
return View();
}
So now my question is:
How can I pass the default values from the radio buttons if the user doesn't interacts with them (i.e. passing the default values I've set upon page load)???
Give this a try:
$('input:radio[name="type"]').filter('[value="1"]').attr('checked', true);
$('input:radio[name="shipping"]').filter('[value="1"]').attr('checked', true);

Have function called based on default dropdown selection

I am trying to redirect a customer to another page using Javascript, if a country other than the US is chosen in a dropdown field. I got it to work, but registered guests have their country default in the dropdown and the function doesn't get called unless the user switches it.
This is the code as it stands now
$(document).ready(function(){
var una = "ok";
$("#shipping-country").change(function(event){
if(($("#shipping-country").val() != "US") &&(una=="ok")){
iCheckout.insertForm();
$("#iCheckoutForm").submit();
}
});
});
How can I rewrite this to have it redirect if a country other than the US is already chosen by default?
It seems you want to check whether their default value is not the US on page load as well as when the value of the dropdown changes?
I'd refactor it a bit:
$(document).ready(function(){
var una = "ok";
var checkIfUS = function() {
if(($("#shipping-country").val() != "US") &&(una=="ok")){
iCheckout.insertForm();
$("#iCheckoutForm").submit();
}
};
checkIfUS(); // check if it should redirect after dom load
$("#shipping-country").change(function(event){
checkIfUS(); // check if it should redirect on form change
});
});
Alternatively, if you're populating the dropdown with javascript, you can add checkIfUS() as a callback to whatever populates the dropdown.
like this
$(document).ready(function(){
var una = "ok";
$("#shipping-country").change(function(event){
if(($("#shipping-country").val() != "US") &&(una=="ok")){
iCheckout.insertForm();
$("#iCheckoutForm").submit();
}
});
if ($("#shipping-country").val() != 'US') {
// your redirect code here
window.location.replace("http://stackoverflow.com");
}
});

Categories