Alpine JS: two-way binding converted input values? - alpine.js

I'm calculating a hex color value from a set of HSL sliders.
When I change the sliders (which are bound to the HSL inputs via x-model), the hex input changes accordingly.
I am completely stuck when trying to get it to work backwards.
How can I change the HSL values when I type in a hex value in the bottom input?
https://codesandbox.io/s/agitated-williams-p54t1?file=/index.html
<body x-data="{h1: h1, s1: s1, l1: l1 }">
<input type="range" min="0" max="360" step="1" x-model="h1" />
<input type="number" min="0" max="360" x-model="h1"/>
<br>
<input type="range" min="0" max="100" step="1" x-model="s1" />
<input type="number" min="0" max="100" x-model="s1"/>
<br>
<input type="range" min="0" max="100" step="1" x-model="l1" />
<input type="number" min="0" max="100" x-model="l1"/>
<br>
<input type="text" id="hex1" x-bind:value="hslToHex(h1, s1, l1)" />
<input type="color" id="hex1" x-bind:value="hslToHex(h1, s1, l1)" />
</body>
<script>
var h1 = 50;
var s1 = 50;
var l1 = 50;
function hslToHex(h, s, l) {
l /= 100;
const a = s * Math.min(l, 1 - l) / 100;
const f = n => {
const k = (n + h / 30) % 12;
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color).toString(16).padStart(2, '0'); // convert to Hex and prefix "0" if needed
};
return myHex = `#${f(0)}${f(8)}${f(4)}`;
};
</script>

To get the reverse scenario working, you first need a hexToHsl function since the input is going to be a hex color code (string).
I have made use of the question to get the function that does the conversion from hex string to the HSL values.
Moreover, I have extracted the alphine.js component logic according to the documentaion to a function since it has more complex functions (it is optional, but a best practice to follow) with the relevant data and functions in it.
I have used the input event handler to the text input so that, it will trigger on any input given to it. (#input="setHSL")
So finally, your component will be as follows,
<body x-data="app()">
<input type="range" min="0" max="360" step="1" x-model="h1" />
<input type="number" min="0" max="360" x-model="h1" />
<br />
<input type="range" min="0" max="100" step="1" x-model="s1" />
<input type="number" min="0" max="100" x-model="s1" />
<br />
<input type="range" min="0" max="100" step="1" x-model="l1" />
<input type="number" min="0" max="100" x-model="l1" />
<br />
<input type="text" id="hex-text" #input="setHSL" :value="hslToHex(h1, s1, l1)" />
<input type="color" id="hex-color" :value="hslToHex(h1, s1, l1)" />
</body>
<script>
function app() {
return {
h1: 50,
s1: 50,
l1: 50,
setHSL(event) {
let hex = event.target.value;
// do this only if its a valid hex string
if(/^(#)((?:[A-Fa-f0-9]{3}){1,2})$/.exec(hex)){
let hsl = this.hexToHsl(hex);
this.h1 = hsl.h;
this.l1 = hsl.l;
this.s1 = hsl.s;
}
},
hslToHex(h, s, l) {
l /= 100;
const a = (s * Math.min(l, 1 - l)) / 100;
const f = (n) => {
const k = (n + h / 30) % 12;
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
return Math.round(255 * color)
.toString(16)
.padStart(2, "0"); // convert to Hex and prefix "0" if needed
};
return (myHex = `#${f(0)}${f(8)}${f(4)}`);
},
hexToHsl(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
var r = parseInt(result[1], 16);
var g = parseInt(result[2], 16);
var b = parseInt(result[3], 16);
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b),
min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
s = s * 100;
s = Math.round(s);
l = l * 100;
l = Math.round(l);
h = Math.round(360*h);
return {h : h, s: s, l:l};
}
};
}
</script>
I also have done an additional check before converting the string to HSL, since there can be invalid inputs for the functions. So the regular expression used here to filter out the hex color codes only. So the conversion will take place only for valid inputs.

Related

Sorting HTML cant get an output

I'm new to this page. I have some problem regarding this sorting that I made. This is the code:
<html>
<body>
<p>Enter First Number:<input type="text" id="1"></p>
<p>Enter Second Number:<input type="text" id="2"></p>
<p>Enter Third Number:<input type="text" id="3"></p>
<p>Enter Fourth Number:<input type="text" id="4"></p>
<p>Enter Fifth Number:<input type="text" id="5"></p>
<button type="button" onclick="SortThis()" >Sort</button>
<script>
function SortThis()
{
var tempVar;
var x;
var y;
var numbers = new Array[];
numbers[0]=document.getElementById("1");
numbers[1]=document.getElementById("2");
numbers[2]=document.getElementById("3");
numbers[3]=document.getElementById("4");
numbers[4]=document.getElementById("5");
for(x=0; x<=4 ; x++)
{
for(y=0; y<=4; y++)
{
if(numbers[x]<numbers[y])
{
tempVar=numbers[x];
numbers[x]=numbers[y];
numbers[y]=tempVar;
} } } }
for(var x=0; x<=numbers.length ; x++)
{
var output =document.getElementById("output");
output.innerHTML=(numbers[x] + " , ");
}
</script>
<p id="output"></p>
</body>
</html>
The problem here is that I can't get an output. I want an output that will print using innerhtml.
Array will be declared as Array() not [] the append statment will be this output.innerHTML += numbers[x]+',';
and to take value you should give numbers[0]=document.getElementById("1").value; not numbers[0]=document.getElementById("1");
I am not very good with the formatting !

Annual Rent divided by square feet display with two decimal points. (i.e. 1,000.38)

I am trying to get the Annual Rent displayed with two decimals and the rent/sq. ft. to have two decimals as well. I've already added the scripting to have these two fields automatically display dollar ammounts and commas.
Any help would be appreciated!
<body>
<table border="1" width="620" style="width: 620px; height: 58px">
<tr>
<td width="82" align="center" height="16"><font face="Arial" size="2">Sq.
Ft.</font></td>
<td width="90" align="center" height="16"><font face="Arial" size="2">Annual
Rent</font></td>
<td align="center" height="16" style="width: 104px"><font face="Arial" size="2">
Rent/Sq. Ft.</font></td>
</tr>
<tr>
<td width="82" align="center"><font face="Arial" size="2">
<input type="text" name="SF_Tenant1" id="sqft1" OnKeyUp="calcRentSQFTOne()"
size="10" value="Sq. Ft.:" tabindex="602" class="style4"></font></td>
<td width="90" align="center"><font face="Arial" size="2"><input type="text"
name="AnnualRent_Tenant1" id="annualrent1" OnKeyUp="calcRentSQFTOne()" size="11"
value="Annual Rent:" tabindex="604"></font></td>
<td align="center" style="width: 104px;"><font face="Arial" size="2">
<input type="text" name="RentSF_Tenant1" id="rentsqft1"
readonly="readonly" size="11" value="Rent/Sq. Ft.:" tabindex="605"></font></td>
</tr>
</table>
<input type="submit"
value="Save" name="Save" tabindex="999" style="font-family: Arial;
font-size: 10pt; width: 65px; height: 29px;"></font></p>
<script type="text/javascript">
//calculation script
function calcRentSQFTOne(){
SquareFeet1 = document.getElementById("sqft1").value;
AnnualRent1 = document.getElementById("annualrent1").value;
document.getElementById("rentsqft1").value =
(AnnualRent1 * 1)
/ (SquareFeet1 * 1);
}
//Dollar format
function formatNumber(number, digits, decimalPlaces, withCommas)
{
number = number.toString();
var simpleNumber = '';
// Strips out the dollar sign and commas.
for (var i = 0; i < number.length; ++i)
{
if ("0123456789.".indexOf(number.charAt(i)) >= 0)
simpleNumber += number.charAt(i);
}
number = parseFloat(simpleNumber);
if (isNaN(number)) number = 0;
if (withCommas == null) withCommas = false;
if (digits == 0) digits = 1;
var integerPart = (decimalPlaces > 0 ? Math.floor(number) : Math.round(number));
var string = "";
for (var i = 0; i < digits || integerPart > 0; ++i)
{
// Insert a comma every three digits.
if (withCommas && string.match(/^\d\d\d/))
string = "," + string;
string = (integerPart % 10) + string;
integerPart = Math.floor(integerPart / 10);
}
if (decimalPlaces > 0)
{
number -= Math.floor(number);
number *= Math.pow(10, decimalPlaces);
string += "." + formatNumber(number, decimalPlaces, 0);
}
return string;
}
</script>
</body>
Likely there is a better solution. A hacky solution to round to two decimal digits:
return Math.round(input*100)/100;
I.e. if you want to round 10.678 to two digits, then first multiply by 100: you get 1067.8, then call Math.round to get 1068 then divide by 100 to get 10.68, which is the desired answer.

How to set both xPath query in one query?

Here is my totally code:-
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
var xml;
$.get(
"xml_converted.xml",
null,
function (data) {
xml = data;
},
"xml"
);
function get_node(ls)
{
var elName = $('#select').val();
var value = $('#value').val();
var xPath = '//*[translate(translate(translate("' + elName + '","-","")," ",""),":","") '+ ls +' translate(translate(translate(#value,"-","")," ",""),":","")]/../../#value';
var iterator = xml.evaluate(xPath, xml.documentElement, null,
XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
var thisNode = iterator.iterateNext();
var str = '';
while (thisNode) {
if (str) {
str += ', ';
}
str += thisNode.textContent;
thisNode = iterator.iterateNext();
}
$("#result").text(str);
if (str == null || str == "")
return false;
else
return true;
}
</script>
</head>
<body>
<input type="text" id="select">
<input type="text" id="value">
<input type="button" value="Less than" onclick="get_node('>')">
<input type="button" value="Grater than" onclick="get_node('<')">
<input type="button" value="Equal" onclick="get_node('=')">
<div id="result">
</div>
</body>
</html>
This is my xml fiel sample :-
<products>
<product_id value="1">
<tab_id value="351">
<tab_name value="test1"/>
<dist_region value="5,5068,5069"/>
<reg_str_dt value="2013-01-14 20:35:00"/>
<individual_strdt value="2013-01-14 20:35:00"/>
</tab_id>
</product_id>
<product_id value="2">
<tab_id value="352">
<tab_name value="test2"/>
<dist_region value="5,5069,5070"/>
<reg_str_dt value="2013-01-14 20:35:00"/>
<individual_strdt value="2013-01-14 20:35:00"/>
</tab_id>
</product_id>
</productS>
In my xml file I have one tab dist_region_value="5,5069,5070" this type of value for check this I have one xpath:-
var xPath = '//*[contains(concat(#value, ","),"' + elName+ ',")]/../../#value';
and another xpath query is :-
var xPath = '//*[translate(translate(translate("' + elName + '","-","")," ",""),":","") '+ ls +' translate(translate(translate(#value,"-","")," ",""),":","")]/../../#value';
How to set both in one query?
thanks...
How about this:
var xPath = '//*[contains(concat(#value, ","), "' + elNname+ ',") and ' +
' translate("' + elName + '"," -:","") '+ ls +
' translate(#value," -:","")]/../../#value';
as shown here, you don't need to nest multiple translates together, either.

Subtraction date between date input in text box and date now using JQUERY,Ajax

I have HTML code as below:
<script type="text/javascript">
$(document).ready(function(){
$("#useDatePicker").mouseout(function{
//$("#result").text() = $("#useDatePicker").text();
alert(1);
});
});
</script>
</head>
<body>
<form method="post" name="frm" id="myForm">
<input type="text" name="date" id="useDatePicker"/>
<input type="text" name="result" id="result" />
</form>
What I need:
when the user select date from date Picker, it will subtract with date now automatic and the result will be in <input type="text" name="result" id="result" />
Problem
I have no concept with it.
may be you can use onselect option of date picker of jquery ui
demo: fiddle
$('#useDatePicker').datepicker({
onSelect: function (date) {
var today = new Date();
var result = DateDiff(today, new Date(date));
$('#result').val(result);
}
});
function DateDiff(date1, date2) {
var diff = date1 - date2;
var num_years = diff / 31536000000;
var num_months = (diff % 31536000000) / 2628000000;
var num_days = ((diff % 31536000000) % 2628000000) / 86400000;
return Math.floor(num_years) + "years " + Math.floor(num_months) + "months " + Math.floor(num_days) + "days";
}

Scriptaculous slider price range slider with two handle

I'm using Scriptaculous to create a price range slider with two handles says minimum and maximum values. How can I store minimum and maximum values in separate hidden field.
Current script as follows,
<div id="price-range" class="filter-track">
<span id="price-min" class="filter-handle" title="Scroll to set your minimum value">>></span>
<span id="price-max" class="filter-handle" title="Scroll to set your maximum value"><<</span>
</div>
<input type="hidden" name="price" id="beds" value="0,100"/>
var loadPriceSlider = function () {
var handles = [$('price-min'), $('price-max')];
// horizontal slider control with preset values
new Control.Slider(handles, 'price-range', {
range:$R(0, 5000, false),
sliderValue: [0, 3000],
values: [0, 100, 200, 300],
restricted: true,
onChange: function(v){
$('price').value = v;
}
});
};
It will store comma separated (min,max) values in price field. but i would like to store this in separate field. How to do this? Any help please?
Your code tries to refer to $('price') but you the input with the name 'price' has the 'id' of 'beds'.
Here's corrected HTML which has the price field, and an additional field:
<div id="price-range" class="filter-track">
<span id="price-min" class="filter-handle"
title="Scroll to set your minimum value">>></span>
<span id="price-max" class="filter-handle"
title="Scroll to set your maximum value"><<</span>
</div>
<ul>
<li>price: <input type="text" name="price" id="price" value="0,100"/></li>
<li>myRange <input type="text" name="myRange" id="myRange" value="0,100"/></li>
</ul>
And the JavaScript:
var handles = [$('price-min'), $('price-max')];
// horizontal slider control with preset values
new Control.Slider(handles, 'price-range', {
range: $R(0, 5000, false),
sliderValue: [0, 3000],
values: [0, 100, 200, 300],
restricted: true,
onChange: function(val){
$('price').value = val;
$('myRange').value = val;
}
});
This works, loading these JavaScript:
<script src="https://ajax.googleapis.com/ajax/libs/prototype/1.7.0.0/prototype.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/scriptaculous/1.9.0/scriptaculous.js?load=slider"></script>

Resources