Updating elements with jQuery selector - javascript

I have a situation where I have the following form elements:
<label for="edit-type-config-associated-element--2">Destination Data Element </label>
<input type="text" id="edit-type-config-associated-element--2"
name="type_config[associated_element]" value="23" size="60"
maxlength="128" class="form-text ajax-processed"
style="visibility: hidden;">
<input type="text" id="edit-type-config-associated-element--2_display"
value="23" size="60" maxlength="128"
class="form-text ajax-processed dropdowntree_aux dropdowntree_input valid"
readonly="" style="top: 61.515625px; left: 15px; position: absolute;
width: 389px; height: 16px;">
I would like to add a change listener to the second input element (identified by edit-type-config-associated-element--2_display) and then change the input in the first input element (identified by edit-type-config-associated-element--2). The catch here is that everytime this form is displayed the number appearing at the end of both ids increments by one (why they couldn't use a consistent id, I have no idea but it is what I am stuck with).
Here is the javascript I am using to try and accomplish this:
// Add a change listener to associated element link for dc mappings
$('.dropdowntree_input').live('change', function () {
// Get the data element id
var dataElementID = $.trim($(this).val()),
dataElementLinks = Drupal.settings.data_element_links;
console.log('text field has changed to: ' + dataElementID);
if (dataElementLinks.hasOwnProperty(dataElementID)) {
$('#linked_form_elements').show();
} else {
$('#linked_form_elements').hide();
}
// Update the underlying text input to contain the right value.
$(':input[type="text"][name="type_config[associated_element]"]').val(dataElementID);
However this is not working. It seems that this function is never called when the second textfield is updated.
Any ideas where I have gone off the rails?
Thanks.

Looks like you were missing a [ in your selector
$('input[type="text"][name="type_config[associated_element]"]').val(dataElementID);
^ here
Also if you are using jQuery >= 1.9 then .live() is no longer supported.
If you are using jQuery >= 1.7 then use .on() instead, also since the first and second inputs are next/prev siblings you can use that relationship to find the element
$(document).on('change', '.dropdowntree_input', function () {
var dataElementID = $.trim($(this).val()),
dataElementLinks = Drupal.settings.data_element_links;
console.log('text field has changed to: ' + dataElementID);
if (dataElementLinks.hasOwnProperty(dataElementID)) {
$('#linked_form_elements').show();
} else {
$('#linked_form_elements').hide();
}
//since the hidden element is the previous sibling
$(this).prev().val(dataElementID);
})

Related

Use addEventListener() to access multiple objects

I want my checkboxes's label to highlight when on and off (like a IRL switch) and I'm not figuring out how to reach all of them without having to make a listener for each of them (I belive there must be some way)
Checkboxes be like:
<label id="labeltest"><input id="checkboxtest" type="checkbox" name="diet" value="Egg" hidden/>Egg</label>
JS be like:
var labeltest = document.getElementById("labeltest")
labeltest.addEventListener("click", function () {
if (this.firstChild.checked) {
this.classList.remove("unchecked")
this.classList.add("checked")
} else if (this.firstChild.checked === false) {
this.classList.remove("checked")
this.classList.add("unchecked")
}
});
I've tried with class instead of ID but didn't work
Also tried something like this with classes to make labeltest an array:
labeltest.forEach(element => {
element.addEventListener("click", function () {
(FUNCTION HERE)
});
But didn't work either
You don't need any JavaScript to accomplish this.
If you reorder your input and labels like this:
<input id="diet-egg" type="checkbox" name="diet" value="Egg" hidden/>
<label for="diet-egg">Egg</label>
Important: Be sure that the for attribute value matches the id of the input the label is connected to. This enables checking and unchecking the checkbox by clicking the <label> element.
Then you can use the adjacent sibling selector + to define the styles of the label whenever the input is checked and unchecked.
input + label {
/* unchecked label styles */
}
input:checked + label {
/* checked label styles */
}

Jquery result in its relative div

I am facing a problem that i have multiple DIVs with almost same ID but having increments from 0 to any number in the end, I want to use this username check function for every different username field and show its results in its specific related div. I tried all the possible ways but its not working.
Here is my Fiddle
Here is my Code
$(document).ready(function() {
$('[id^=Loading]').hide();
});
function check_username(){
var username = $("[id^=username]").val();
if(username.length > 1){
$('[id^=Loading]').show();
$.post("username-Check.php", {
username: $('[id^=username]').val(),
}, function(response){
$('[id^=Info]').fadeOut(2100);
$('[id^=Loading]').fadeOut(2100);
setTimeout("finishAjax('Info', '"+escape(response)+"')", 2000);
});
return false;
}
}
function finishAjax(id, response){
$('#'+id).html(unescape(response));
$('#'+id).fadeIn(2000);
}
Incremental/dynamic id attributes are almost always an anti-pattern and should be avoided where possible as they create more problems than they solve.
A much better solution would be to use DOM traversal to find the elements related to the one which raised the event - in your case the blur on the input.
To do this, firstly use unobtrusive event handlers instead of the outdated on* event attributes. Then change the id attributes to classes. To find the elements, use the this keyword to reference the element that raised the event, then prev() and prevAll().first() to find the required element by its class. Finally, provide an anonymous function to setTimeout() over hacking together a string to be run through eval(). Try this:
<div class="info"></div>
<span class="loading"></span>
<input class="username form-control" type="text" name="txtengine" placeholder="914899" value="" /><br>
<div class="info"></div>
<span class="loading"></span>
<input class="username form-control" type="text" name="txtengine" placeholder="914899" value="" /><br>
$(document).ready(function() {
$('.loading').hide();
});
$('.username').on('blur', function() {
var username = $(this).val();
if (username.length) {
var $loading = $(this).prev('.loading').show();
var $info = $(this).prevAll('.info').first();
$.post("username-Check.php", {
username: username,
}, function(response) {
$info.fadeOut(2100);
$loading.fadeOut(2100);
setTimeout(function() {
$info.html(response).fadeIn(2000);
}, 2000);
});
}
})
Working example
Note that the example in the fiddle had the AJAX request logic amended to fit jsFiddles' JSON response logic, but the functionality is the same.
Before I start answering I would strongly suggest you to use a class and then select via class name. As it seems your case is textbook for when to use jquery class-selectors.
You cannot use the attribute selector without specifying what you are using it on. I.e. you cannot say:
$('[id^=Loading]')
you need to give the tag name, the id, or the class i.e.
$('span[id^=Loading]')
I have made a jfiddle for you:
https://jsfiddle.net/acc069me/6/

Animated form, how to check input value on page refresh?

I have a form which uses dynamic styling. Consider this html
<div class="field-name field-form-item">
<label class="placeholder" for="name">Name</label>
<input class="form-input" id="name" type="text" name="name" maxlength="50" size="30">
</div>
The label is ABOVE the input, with CSS. When you click the label :
$('.placeholder').on('click focus', function() {
$(this).addClass('ph-activated');
$(this).siblings('input').focus();
})
Then the label is animated and let the user type in the input.
If the user dont wan't to write anything, the animation goes back, and hide input field :
$('input').on(' blur', function(){
if ($(this).val().length === 0) {
$(this).siblings('label').removeClass('ph-activated');
}
});
That's alright.
But when a user fill the input, THEN refresh the page and its browser didn't reset input fields(ie firefox) : the label is above the input, even if the latter is not empty.
I tried this :
$(document).ready(function() {
if ($('input').val().length) {
$(this).siblings('label').addClass('ph-activated');
}
})
But it doesn't seem to trigger, I tried several ways to write this function. Up to now I never managed to give the class ph-activated to a label with a filled input on page refresh.
Sorry I can't fiddle this. I just have far too much html/css/js/php to copy paste
Well you are targeting wrong element in $(document).ready because you are referring label with this thinking that $(this) is input whereas it is document. So try applying below code and I hope there will be multiple input elements in page, so I've used $.each and looping through all the inputs
$(document).ready(function() {
$('input').each(function(){ //loop through each inputs
if ($(this).val().length) {
$(this).siblings('label').addClass('ph-activated');
}
});
})
DEMO - Inspect the label and you will find ph-activated class added to label
Try this one:
$(document).ready(function() {
var length = $('input').filter(function( index ) {
return ($(this).val() !== '');
}).length;
if (length > 0) {
$(this).siblings('label').addClass('ph-activated');
}
})

Change text label where inside there are an input checkbox element

I have this part of html on my form:
<label class="ideal-radiocheck-label" onclick="">
<input id="pagamento_8" class="_input " type="checkbox" onclick="half(this,value);" checked="" value="980" name="pagamento[]" style="position: absolute; left: -9999px;" autocomplete="off">
<span class="ideal-check checked"></span>
988 (980-980 €)
</label>
It is a checkbox input button that call the function half() to make something like call the next function:
function setClickedLabel(clicked,new_value){
label_e=$(clicked).parent();
label_t=$(label_e).text();
labels_t=label_t.split('-');
$(label_e).html(labels_t[0]+'-'+new_value+' €)'); <-- 1
//$(label_e).text(labels_t[0]+'-'+new_value+' €)'); <-- 2
//$(label_e).innerHTML = labels_t[0]+'-'+new_value+' €)'; <-- 3
}
Here i would change a part of the label "988 (980-980 €)" (the last 980) and the "clicked" variable is the input object that you can see inside the label element.
Using one of the three methods reported i got 2 effect. Whit 1,2 it changes the label but it removes the input element. Whit 3 it doesn't make nothing.
What function i can use? How i must fix the code to get what i need?
Html can't be changed.
Maybe another alternative without appending.
tnx,
j.
Adapting the script on jsfindle left on the comment from adeneo i have wrote that solution. Maybe can be other better solutions.
function setClickedLabel(clicked,new_value,old_value){
label = $(clicked).parent().contents().filter(function() {
return this.nodeType === 3 && this.nodeValue.trim().length;
}).get(0);
label.nodeValue = label.nodeValue.replace(new RegExp("-"+old_value), "-"+new_value);
}

Disabling a textbox when the other textbox have a value HTML

im sorry for this question but how can i disable a textbox if another textbox have a value??
I already try this code but its not working,, sorry for the noob question T_T
function disable(downpayment,full_payment)
{
if ( downpayment.value.length >= 1 )
document.getElementById(full_payment).disabled = true;
else
document.getElementById(full_payment).disabled = false;
}
</script>
<input name="downpayment" id="downpayment" type="text" onselect="function disable(downpayment,full_payment);" style="width:250px" />
</p>
<p>
<input name="full_payment" id="full_payment" type="text" style="width:250px" />
If you want to stay with plain JavaScript:
// finding the relevant elements *outside* the function
var downpayment = document.getElementById('downpayment'),
full_payment = document.getElementById('full_payment');
function enableToggle(current, other) {
/* 'current' is the element that currently has focus
'other' is the other input element, that does not have focus.
1. if the 'current' value of the focused/active element, once the whitespace
is removed, is greater than 0 (so it has something in it other than whitespace,
the disabled property of the 'other' element is true,
2. if the 'current' element has only whitespace, and/or a zero-length value,
the 'other' element's disabled property is false.
*/
other.disabled = current.value.replace(/\s+/,'').length > 0;
}
// using the onkeyup event to call a function on the elements.
downpayment.onkeyup = function () {
enableToggle(this, full_payment);
}
full_payment.onkeyup = function () {
enableToggle(this, downpayment);
}
This works with the following HTML:
<input name="downpayment" id="downpayment" type="text" style="width:250px" />
<input name="full_payment" id="full_payment" type="text" style="width:250px" />
JS Fiddle demo.
If you're using jQuery already, then you can either nest the above into jQuery's $(document).ready(function(){ /* the code in here */});, or switch to a jQuery-only solution, such as Alex's.
To stick with plain-JavaScript, and avoiding explaining how to set up an equivalent DOM-ready event, put the following at the end of your HTML content, just before the closing </body> tag:
<script>
var downpayment = document.getElementById('downpayment'),
full_payment = document.getElementById('full_payment');
function enableToggle(current, other) {
other.disabled = current.value.replace(/\s+/,'').length > 0;
}
downpayment.onkeyup = function () {
enableToggle(this, full_payment);
}
full_payment.onkeyup = function () {
enableToggle(this, downpayment);
}
</script>
(This is exactly the same JavaScript as above, with the comments stripped out, but wrapped in <script></script> tags)
Putting this at the bottom of the HTML means that the elements exist in the DOM prior to your trying to assign event-handlers to them.
Incidentally, with adjusted HTML, to give:
<form>
<!--
I associated the relevant elements with a class-name 'enableToggle',
you don't have to, it just reduces the work the jQuery has to do later
when using siblings('.enableToggle') to find the relevant elements.
-->
<div>
<label for="downpayment">Downpayment</label>
<input name="downpayment" class="enableToggle" id="downpayment" type="text" style="width:250px" />
<label for="full_payment">Full payment</label>
<input name="full_payment" class="enableToggle" id="full_payment" type="text" style="width:250px" />
</div>
</form>
The following jQuery could be used:
// binds both event-handler to both 'keyup' and 'paste' events.
$('.enableToggle').on('keyup paste', function(){
/* 'curVal' is a Boolean (true or false) depending on whether there's
a value other than whitespace */
var curVal = $(this).val().replace(/\s+/g,'').length > 0;
/* sets the 'disabled' property of the sibling elements of the current
element, as long as those siblings have the class 'enableToggle'
(this avoids having to explicitly identify all the elements you want
to act on). */
$(this).siblings('.enableToggle').prop('disabled', curVal);
});
JS Fiddle demo.
You have tagged the question jQuery, so it's as simple as...
$("#downpayment").on("change paste", function() {
$("#full_payment").prop("disabled", this.value.length);
});
As soon as your down payment has some content in it (even if it's a space, if that's not ideal, $.trim() the input before you check its length property) then it will enable the full payment.
$(document).ready(function()
{
$(".PaxHeads").on('keypress','input[name="DebitAmount"]',function()
{
var myLength = $('input[name="DebitAmount"]').val().length;
if (myLength!=0)
{
$('input[name="CreditAmount"]').attr("disabled", "disabled");
}
else
{
$('input[name="CreditAmount"]').removeAttr("disabled");
}
});
$(".PaxHeads").on('keypress', 'input[name="CreditAmount"]', function()
{
var myLength1 = $('input[name="CreditAmount"]').val().length;
if (meLength1!=0)
{
$('input[name="DebitAmount"]').attr("disabled", "disabled");
}
else
{
$('input[name="DebitAmount"]').removeAttr("disabled");
}
});
});

Categories

Resources