Swap Divs then swap selected option value between two select lists - javascript

The Problem:
Before I began adding the div swaps, I could only type into the left (from_value) input and the result of the calculations would be applied via ajax to the right (to_value) input.
I would like to allow the user to type into either box and have the results display in the opposite box they're typing in.
What I am doing to make this happen:
I am swapping the left div with the right div on mouseover of the to_value input. Here's the code i'm using to do the swap:
$.fn.swapWith = function (that) {
var $this = this;
var $that = $(that);
// create temporary placeholder
var $temp = $("<div>");
// 3-step swap
$this.before($temp);
$that.before($this);
$temp.after($that).remove();
return $this;
};
var leftSide = $('#left-side');
var rightSide = $('#right-side');
$('#to_value_input').on('mouseover', function () {
$(rightSide).swapWith(leftSide);
});
This effectively swaps the divs, bringing along with it ids and names of the inputs which retains functionality of my server-side script to perform calculations. As expected, the from_unit select list and to_unit select list are swapped and their values / displayed text are also swapped from one side to the other.
I would like to swap the values and text of the two select boxes either directly before or more likely, directly after the div swap so it appears as if nothing changed on screen.
Similar questions that I have reviewed:
How to swap values in select lists with jquery?
How to swap selected option in 2 select elements?
I have tried several variations of each of the provided solutions. This seems like it should be a fairly simple thing to do but I find myself stuck. Any further help would be greatly appreciated.
The full code base is available on github if you need to see it: https://github.com/pschudar/measurement-conversion
I have made minor changes to the code hosted there to accommodate the div swaps.

Related

Change product image by selecting only one attribute in Woocommerce Variable Products

This relates to an online clothing store. We have variable products set up with colour and size attributes, for example a product might have 2 variations; Green/Any Size and Black/Any Size.
There is an image of the product in the corresponding colour for each variation, but at the moment the image doesn't switch unless a colour AND size is selected (I'm aware this is how Woo works out of the box). We would like to make it so that the image switches when JUST a colour is selected.
I have come accross this code on SO and another site. It allows a product variation image to change when only the one main attribute is selected (e.g. color), rather than having to select all variation attributes (e.g color and size) in order for the image to change.
This code was written to work with a plugin, however the person who wrote it mentioned changing line 6 in order to use without plugins.
Can someone help me to adjust this code to my ecommerce store? I know that this can be easly done by someone who understand JS, but since I am not a developer it's really hard for me. I hope someone could help!
var image_to_show = '';
var variations = JSON.parse($(".variations_form").attr("data-product_variations"));
if(variations) {
var first_attr = Object.keys(variations[0].attributes)[0];
// when swatch button is clicked
$("ul[data-attribute_name='"+first_attr+"'] li").click(function() {
var choice = $(this).attr("data-value");
var found = false;
// loop variations JSON
for(const i in variations) {
if(found) continue;
if(variations.hasOwnProperty(i)) {
// if first attribute has the same value as has been selected
if (choice === variations[i].attributes[Object.keys(variations[0].attributes)[0]]) {
// change featured image
image_to_show = variations[i].image_src;
found = true;
}
}
}
});
// after woo additional images has changed the image, change it again
jQuery(".variations_form").on("wc_additional_variation_images_frontend_image_swap_done_callback", function() {
if(image_to_show.length) {
$(".attachment-shop_single").attr("src", image_to_show).removeAttr("srcset");
}
});
}

Making a FormBody Shrink and Expand Using JQuery and SharePoint

I am creating a form in sharepoint. I have an ms-FormBody for a text box. I would like for the user to be able to double click the box in order to expand the box and if they double click again, it will shrink back up. Again this is in SharePoint.
EDIT: Thanks to some help from #Thriggle I am very close to the goal I wanted with this project. The problem now is that Whatever you type will only stay on one line (t ext wrapping maybe?). Also The text box doesn't actually take up less space (This is not a big deal but if you can think of anyway to make the rest of the boxes move as this box resizes) and I was wondering if there is a way that the box will be small when program launches.
Based on your screenshots, I'm assuming that you're using Nintex Forms.
For Plain Text Multi-Line Fields
The following will work for plain text multiline fields, but not for rich text or enhanced rich text fields (neither of which are represented by an ordinary textarea element).
In your form settings, in the Custom JavaScript section, you can add the following code:
ExecuteOrDelayUntilScriptLoaded(function(){setTimeout(checkFieldExists,1000);},"sp.js");
function checkFieldExists(){
// Nintex forms load slowly; we'll hold off on running the code
// until we're able to access the element through the DOM.
var field = document.getElementById(DescriptionID);
if(field){
// The field exists, time to attach an event listener.
addExpansionToggleEvent(field);
}else{
// Wait a second, then check again.
setTimeout(checkFieldExists,1000);
}
}
function addExpansionToggleEvent(field){
field.style.height = ""; // remove the default height=100%
field.ondblclick = function(){
var rows = field.getAttribute("rows");
field.setAttribute("rows",+rows < 10 ? 10 : 1);
};
}
This is assuming you added a client ID of DescriptionID to the plain text multiline field that you want to toggle, as shown in your screenshot.
For Rich Text Multi-Line Fields
Rich text fields are (bizarrely) represented by iframes instead of textarea elements.
The following code can be added to your Custom JavaScript section to provide expand/shrink behavior upon double-clicking a rich text field, but note that this does not readjust the way other controls are laid out on the form to account for the field's new size... so it's not especially useful.
ExecuteOrDelayUntilScriptLoaded(function(){setTimeout(checkFieldExists,1000);},"sp.js");
function checkFieldExists(){
var iframes = document.querySelectorAll("iframe[title=\"Rich Text Editor\"]");
if(iframes.length > 0){
addExpansionToggleEvent(iframes);
}else{
setTimeout(checkFieldExists,1000);
}
}
function addExpansionToggleEvent(iframes){
for(var i = 0, len = iframes.length; i < len; i++){
var body = iframes[i].contentDocument.querySelector("body");
(function(container){
body.ondblclick = function(){
container.height = +(container.height) < 140 ? 140 : 30;
};
})(iframes[i]);
}
}
Again, this code is specifically targeted toward rich text field, and will not work for plain text or enhanced rich text fields.

Repeat Control using jQuery

I'll probably lose reputation for asking this; but I've been trying infinite variations of code, and failing every time. So I'm reaching out.
I'm working on an aspx. It's all built, they just want some additional functionality.
We're using ScriptSharp to trans-compile to JavaScript.
Basically, we've got an HTML table. Each row in the table represents an invoice. One column in the table represents the amount due (call it amountDue) on the invoice. Another column on the table contains a textbox wherein the user may enter the amount to apply to the invoice (call it amountToPay). If the amounts differ, another column populates with a textbox, pre-populated with the difference between the amount due and the amount entered (call it difference). Following this column is another column with a drop-down list of reasons to explain the discrepancy (call it reason). The user may change the difference in the difference textbox. If that happens, a new additional difference textbox and a new additional reason drop-down list need to appear on the same row of the table, each under its appropriate column.
My first attempts duplicated controls geometrically, for example, going from two difference textboxes to eight. I figured that out.
Now every combination of jQuery functions I try either duplicates all the controls, or none of the controls. So, on difference change, either no new difference textbox is added, or the number of difference textboxes that exist is added. So if two exist, four result. If four exist, eight result.
Okay, here's some code.
Here are the two columns for difference and reason.
<td class="currency">
<div>
<input class="difference_textbox" type="text" value="0.00" style="display: none;" />
</div>
</td>
<td>
<div>
<select style="display: none;" class="adj_reason_select">
<option></option>
</select>
</div>
</td>
I'll skip the ScriptSharp and just list the trans-compiled JavaScript (debug version):
// Let this function represent the function called on `difference` change.
ReceivePayment._addAdjustment = function ReceivePayment$_addAdjustment(e) {
var self = $(e.target);
var customerInvoice = self.parents('.customer_invoice');
var amountPaidBox = customerInvoice.find('.amount_to_pay_input');
// ...
var amountPaidTD = amountPaidBox.closest('td');
var diffTextBoxTD = ReceivePayment._duplicateInputControl(amountPaidTD);
var adjReasonSelectTD = ReceivePayment._duplicateInputControl(diffTextBoxTD);
// ...
}
ReceivePayment._duplicateInputControl = function ReceivePayment$_duplicateInputControl(td) {
// This is very verbose so that I can stop at any point and
// examine what I've got.
var o = td.next(); // Grab the next td.
var divs = o.children(); // Grab the div(s) contained within the td.
var div = divs.last(); // Grab the last div within the td.
// And here's where all my gyrations occur, infinite permutations
// of jQuery calls, not one permutation of which has succeeded in
// adding the contents of the final div to the list of divs.
var d = div[0];
var html = d.outerHTML;
var s = html.toString();
div.add(s);
return o;
}
My attempts include calling after, insertAfter, html, clone, cloneNode, appendChild, and on, and on, on different objects, including divs, div, o, etc.
Part of my problem is that I've not worked with jQuery much. I know just enough to be dangerous. But surely this is possible. Given a td, find the following td. Within that td will be a list of one or more divs. Get the last of those divs, copy it, and append that copy to the list of divs. Done.
What, oh what, am I missing? Flame on.
I appear to have stumbled upon the solution after a shameful amount of time spent spinning my wheels. I gave up. Then, of course, it hit me:
ReceivePayment._duplicateInputControl = function ReceivePayment$_duplicateInputControl(td) {
// This is very verbose so that I can stop at any point and
// examine what I've got.
var o = td.next(); // Grab the next td.
var divs = o.children(); // Grab the div(s) contained within the td.
var div = divs.last(); // Grab the last div within the td.
o.append(div.clone());
return o;
}

Simpler function to reset classes, add to target class 'active', and filter map based on different parameters

I'm working on a map project where I built my own UI. Part of it is a navigation where you can filter the map by clicking a div button in a column floating at the edge of the map. It works perfectly fine, currently, but it is overly complicated and will be a major issue to explain how to add new buttons as the data expands.
The gist is that it first defines a variable as the button id, and on click resets all the classes to a default set, except for the button which is clicked gains the class 'active', and executes a function which sets filtering based on an assigned id in the dataset or return true for All.
The way I have it, which is functional but extremely cluttered
Edit: I've made a few changes that substantially reduce the lines, but I still don't know how to combine multiple similar copies of these into a single function
//define variable to point to a specific button
var navigation = document.getElementById('navigation').children;
var all = document.getElementById('filter-all');
....
//[Currently] nine additional variables of nearly the same thing (now just for selecting the button pressed)
//Show all
all.onclick = function() {
navigation.className = navigation.className.replace(new RegExp('\b' + active + '\b'),'');
this.className += ' active'; //for some reason this doesn't actually add the space
map.featureLayer.setFilter(function(f) {
// Returning true for all markers shows everything.
return true;
});
map.fitBounds(map.featureLayer.getBounds());
return false;
};
....
//Followed by nine nearly identical functions that just reset classes, and sets filtering parameters
I know there is a way to combine the functions to do the same thing without so much bulk, but my search is so far fruitless.

JS/JQUERY: Moving numbered table rows up and down without losing user input

I have created a table in HTML, consisting of table rows in a tbody tag.
I've used a javascript code snippet from mredkj.com to be able to add rows and delete them, too. The rows are sorted and their rank is in the first TD (cell) in every TR (row).
Now I would like the add the functionality of being able to manually 'resort' the tablerows.
The problems are:
my javascript/jquery knowledge is
very limited
the ranks of tablerows
do not get updated(when you delete a row, the
rowranks get updated by the
'reorderRows function, but calling this function from within my jQuery does not seem to
sort out the problem)
the user's input in textarea's gets erased as soon as up or down button is clicked.
For example: user adds a TR, that gets added at the bottom of the current list of tablerows, fills in the textarea and desides that the row (s)he filled should be ranked first, so she clicks the up arrow a couple of times, until it's on top.
The rank of the row is now #1 and the input is still in the textarea's.
My questions are:
Does anyone know how I can make the
rows update their ranking when the
user moves the row?
How do I maintain the user's input?
Any help is very much appreciated and if you have any other suggestions, please share them.
Code here: http://jsbin.com/eyefu5/edit - for some reason, the moving up and down doesn't work in js bin, it does however when I run it in my browser.
I updated your code to do what I think you were trying to do: http://jsbin.com/eyefu5/9/
My primary changes were to the following swap logic:
function swap(a, b){
b.before(a);
reorderRows(document.getElementById(TABLE_NAME), 0);
}
function getParent(cell){ return $(cell).parent('tr'); }
$('#diagnosetabel').on('click', '.upArrow', function(){
var parent = getParent(this);
var prev = parent.prev('tr');
if(prev.length == 1){ swap(parent, prev); }
});
$('#diagnosetabel').on('click', '.downArrow', function(){
var parent = getParent(this);
var next = parent.next('tr');
if(next.length == 1){ swap(next, parent); }
});
The biggest difference is that I switched the swap code to using jQuery's before method, which should take care of just about everything for you. I also added a call to the reorderRows method which you were already using. At the moment it starts at the beginning and reorders all the numbers after the swap, but you could narrow this down as needed because you know the only two rows which were modified.
Hope that helps!

Categories