how can I add a wildcard with jquery binding - javascript

how can I add a wild card into this jquery bind event so that form fields with 'PauNumber' are ignored? This field is repeated for each entity. Unfortunately I can't easily assign a css class to it because the text box is created server side.
many thanks
<div class="PassengerWrapper">
<input type="text" value="" name="PauNumber0" id="PauNumber0">
</div>
<div class="PassengerWrapper">
<input type="text" value="" name="PauNumber1" id="PauNumber1">
</div>
<div class="PassengerWrapper">
<input type="text" value="" name="PauNumber2" id="PauNumber2">
</div>
$('.PassengerWrapper input[type=text], .PassengerWrapper select').not(':hidden').each(function () {

You can do it inside the .not('selector') to filter the elements you don't want
$('.PassengerWrapper input[type=text], .PassengerWrapper select').not(':hidden,input[name*=PauNumber]').each(function () {
You can use [name*=PauNumber] or [id*=PauNumber]
Here's an example fiddle for you http://jsfiddle.net/XQWmf/
Also link to the different selectors

Related

How to get id of a dynamic input field in javascript

I want to create a dynamic form where I also apply JavaScript to the dynamic elements.
What I want to do right now is figure out which field (stored in array or whatever data structure) in JavaScript has been clicked so that I can apply the script to that particular field.
The HTML looks like this:
<div class="triple">
<div class="sub-triple">
<label>Category</label>
<input type="text" name="category" id="category" placeholder="Classes/Instances" required/>
<ul class="cat-list"></ul>
</div>
<div class="sub-triple">
<label>Relation</label>
<input type="text" name="relation" id="relation" placeholder="Properties" required/>
<ul class="rel-list"></ul>
</div>
<div class="sub-triple">
<label>Value</label>
<input type="text" name="value" id="value" placeholder="Classes/Instances" required/>
<ul class="val-list"></ul>
</div>
</div>
This "triple" div is dynamic and I want to create as many "triples" as the user wants, that also means the input fields of inside the "triple" section increase as well.
I'm confused on how to add javascript to one element of the input. For example I have inputs: category, relation and value and the user wanted 2 or more triples then the input ids could look like category2, relation2 and value2 or something similar to that.
let category = document.getElementById("category");
category.addEventListener("keyup", (e) => {
removeElements();
listDown(category, sortedClasses, ".cat-list")
});
If I lets say clicked on category2 for instance how do I tell that to my javascript since these fields are completely dynamic.
Summary: The user is adding repeat sections of triples (containing 3 input elements), where the id of each input element is generated dynamically. My script above works for the first triple section only as the ids are fixed, as for successive "triple" section the id of the fields get changed. How do I identify (see which element has been clicked) and get these dynamic ids
Try listening to the parent element and then using the event's target to figure out the identity of the input. Since the child elements events will bubble up you'll be able to listen to all children
e.g.
let parentElement = document.querySelector(".triple");
parentElement.addEventListener("click", (e) => {
console.log(e.target.id);
});
You can use the onfocus event
<div class="triple">
<div class="sub-triple">
<label>Category</label>
<input type="text" name="category" id="category" placeholder="Classes/Instances" onfocus="onFocusCategoryInput()" required/>
<ul class="cat-list"></ul>
</div>
<div class="sub-triple">
<label>Relation</label>
<input type="text" name="relation" id="relation" placeholder="Properties" onfocus="onFocusRelationInput()" required/>
<ul class="rel-list"></ul>
</div>
<div class="sub-triple">
<label>Value</label>
<input type="text" name="value" id="value" placeholder="Classes/Instances" onfocus="onFocusValueInput()" required/>
<ul class="val-list"></ul>
</div>
</div>

Can't select and hide any previous element

I'm about lose my mind with this problem. No form of jQuery selector seems to work in dynamically finding any elements above the link. I'm trying to access an element above the link and hide it. Using things like parent(), prev(), before(), closest(), ect. will show a non-null object but it won't respond to the hide() method.
<div class="row">
<div class="col-xs-5">
<div id="test_fields">
<li id="test_input" class="string input optional stringish">
<label class="label" for="test_input">Ingredient name</label>
<input type="text" name="test_input" value="afsfasf" id="test_input">
</li>
</div>
<input type="hidden" id="recipe_recipe_ingredients_attributes_0__destroy" name="recipe[recipe_ingredients_attributes][0][_destroy]">
Remove Ingredient
</div>
</div>
function remove_fields(link)
{
$(link).prev("input[type=hidden]").val('1'); // this doesn't work
var divToHide = $(link).prev('div');
$(divToHide).hide() // this doesn't work
//$('#test_fields').hide(); //this works
}
Try replacing the link as below:
Remove Ingredient
I'm not sure. But maybe this is the problem. Because I remember that I have had problem with 'this'previously and when I replaced that, it performed the job.
you can try .closest() and .find()
function remove_fields(link) {
$(link).closest('div[class^="col-xs"]').find("input[type=hidden]").val('1');
var div_to_hide = $(link).closest('div[class^="col-xs"]').find('#test_fields');
$(div_to_hide).hide();
//$('#test_fields').hide(); //this works
}
You can't change hidden input's "value" attribute by using .val(). You need to use:
$(link).prev("input[type=hidden]").attr('value', '1');
As I'm not really sure what do you want to do with this input, I'll just let it go like this.
.prev() fn goes only one previous element in the structure. As input is a <a>'s previous element, you can't select div like that. You can use .siblings() for instance.
$(link).siblings('div').hide();
If you break the code in pieces, it gets easier.
First I took the 'Link', from it I grabbed the nearest div above it, then I picked up the input.
I did not make many changes to your code.
function remove_fields(link)
{
var $link =$(link);
var $divToHide = $link.closest('div');
$divToHide.find("input[type='hidden']").val('1');
$divToHide.hide()
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="row">
<div class="col-xs-5">
<div id="test_fields">
<li id="test_input" class="string input optional stringish">
<label class="label" for="test_input">Ingredient name</label>
<input type="text" name="test_input" value="afsfasf" id="test_input">
</li>
</div>
<input type="hidden" id="recipe_recipe_ingredients_attributes_0__destroy" name="recipe[recipe_ingredients_attributes][0][_destroy]">
Remove Ingredient
</div>
</div>

JQuery: how to check if checkbox is checked and add attributes to field

I'm trying to check whether a check box is checked, and if it is checked, then I want to add the "required" attribute to an adjacent text field. I've tried it two different ways with no success. Here are the form elements and my two JQuery attempts.
neither of those will actually trigger the event. My browser either does nothing at all or triggers an "Empty string passed to getElementById()." event
Form elements:
<div class="col-sm-5">
<label id="checkboxNumber-label" class="toplabel" for="checkboxNumber">Checkbox</label>
<g:textField name="checkboxNumber" value="${...checkboxNumber}" class="form-control" required="" aria-labelledby="checkboxNumber-label"/>
<label class="checkbox-inline">
<g:checkBox name="checkboxYesNo" id="checkboxYesNo" value="${...checkboxYesNo}" onclick="chkboxYesChecked()"/>
</label>
</div>
<div class="col-sm-5">
<label id="someTextField-label" class="toplabel" for="someTextField">Some Text Field Here</label>
<g:textField name="someTextField" id="someTextField" value="${...someTextField}" class="form-control" aria-labelledby="someTextField-label"/>
</div>
JQuery:
function chkboxYesChecked(){
if($('#checkboxYesNo').prop('checked')){
$('#someTextField').prop('required',true);
$('#someTextField').append('<span class="required-indicator">*</span>');
}else{
$('#someTextField').removeAttr('required');
}
}
$(document).ready(function() {
$('#checkboxYesNo').click(function() {
if($(this).is(":checked"))
{
$('#someTextField').prop('required',true);
$('#someTextField').append('<span class="required-indicator">*</span>');
} else {
$('#someTextField').removeAttr('required');
}
});
});
With your markup this becomes more convoluted than it needs to be.
$(document).on("click", ".checkbox-inline :checkbox", function () {
var $nextTextbox = $(this).closest("div").next("div").find(":text").first();
if (this.checked) {
$nextTextbox.prop("required", true).after('<span class="required-indicator">*</span>');
} else {
$nextTextbox.prop("required", false).next('.required-indicator').remove();
}
});
Notes
This approach uses event delegation.
There are no IDs involved, because I suppose you need the same thing more than once on your page. Tying it to a specific element ID is counter-productive.
This approach relies on the specific document structure from your sample Grails template. If you want something more flexible and easier-to-read, change your HTML.
This applies to all checkboxes that have a text field in the immediately following <div>. Use CSS classes on your elements to filter it/make it apply to specific ones only.
If there is no immediately following <div> with a text box, the function does nothing.
$(this).is(":checked") is superfluous. You don't need jQuery to find out if the current DOM element is checked. this.checked is a lot simpler and has the same effect.
Don't use inline event handlers (onclick="..."). Ever.
See it in action:
$(document).on("click", ".checkbox-inline :checkbox", function () {
var $nextTextbox = $(this).closest("div").next("div").find(":text").first();
if (this.checked) {
$nextTextbox.prop("required", true).after('<span class="required-indicator">*</span>');
} else {
$nextTextbox.prop("required", false).next('.required-indicator').remove();
}
});
input[required] {
background-color: #FFD1D1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-sm-5">
<label id="checkboxNumber-label" class="toplabel" for="checkboxNumber">Checkbox</label>
<input type="text" name="checkboxNumber" value="${...checkboxNumber}" class="form-control" required="" aria-labelledby="checkboxNumber-label" />
<label class="checkbox-inline">
<input type="checkbox" name="checkboxYesNo" id="checkboxYesNo" value="${...checkboxYesNo}" />
</label>
</div>
<div class="col-sm-5">
<label id="someTextField-label" class="toplabel" for="someTextField">Some Text Field Here</label>
<input type="text" name="someTextField" id="someTextField" value="${...someTextField}" class="form-control" aria-labelledby="someTextField-label" />
</div>

JQuery detects focusOut even if I still focus on input inside the same div. How to change it?

This is my code:
Javascript:
$(".test").on("focusout", function (e) {
$("#output").append("Lost focus<br>");
});
HTML:
Inputs inside div:
<div class="test">
<input type="text" />
<input type="text" />
</div><br>
Inputs outside div:<br>
<input type="text" />
<div id="output">
</div>
I want to detect if user leaves "div.test". Unfortunately, "focusout" works also when I move focus to other object inside this div.
Look at this fiddle: http://jsfiddle.net/Piotrek1/wfukje3g/6/
Click on first input and use Tab to switch through textboxes. "
Lost focus" should appear only if user move out from the div, but it happens always. Why is that and how to change it?
The $ operator returns a collection. You have two inputs inside the <div class="test">. So it matches all elements and children with the .test class.
I think what you want two divs with separate input elements and two different classes OR, use an ID on the actual input element so the $ operator only matches the input id you want this event to fire on. http://jsfiddle.net/wfukje3g/7/
$("#test").on("focusout", function (e) {
$("#output").append("Lost focus<br>");
});
<div class="sometest">
<input id="test" type="text" />
<input type="text" />
</div><br>
Inputs outside div:<br>
<input type="text" />
<div id="output">
</div>
I have implemented piece of code to handle div focus out
$(document).ready(function () {
var count = 1;
$("#name").focusout(function (e) {
if($(this).has(e.relatedTarget).length === 0) {
$("#output").append("<label style='width:100%;'>"+ count++ +" Name div focus out </label>");
}
});
});
Inputs inside div:
<div id="name" class="test">
<input type="text" id="firstname"/>
<input type="text" id="lastname"/>
</div>
Inputs outside div:<br>
<input type="text" id="dob"/>
<div id="output" style="width:100%"></div>
In this piece of code I have used relatedTarget.
relatedTarget will provide the next focused element If next element is not the child of this div then it is div focus out.
Try this in your code.
I hope this will be helpful.
Thanks
JSFIDDLE LINK - Sample code

Change input value on tab

I'm coding a small web app to log team members work time. It all works well, except one thing. When you tab on a fieldset a new page opens with a form to change the time for that person. The first time you tab it works, but when you click on the next fieldset it changes all input fields with the name 'begin-time' ?
I think i'm missing something but I'm not sure what it is.
I have the following form;
<form id="time-form">
<fieldset>
<div class="row">
<input type="text" value="Jonh Doe" id="fullname" name="fullname" readonly="">
<div class="time">
<input type="text" value="00:00" id="begin-time" name="begin-time" readonly="">
<input type="text" value="00:00" id="end-time" name="end-time" readonly="">
</div>
</fieldset>
<fieldset>
<div class="row">
<input type="text" value="Jane Doe" id="fullname" name="fullname" readonly="">
<div class="time">
<input type="text" value="00:00" id="begin-time" name="begin-time" readonly="">
<input type="text" value="00:00" id="end-time" name="end-time" readonly="">
</div>
</fieldset>
</form>
with the new form 'on tab';
<form id="add-time">
<input type="time" name="begin_time">
<input type="time" name="end_time">
</form>
and the javascript;
$$('#time-form fieldset').tap(function() {
var beginTime = $(this).find("[name='begin-time']");
$('#add-time input[name=begin_time]').change(function() {
beginTime.val(this.value);
});
$$('.add-time').tap(function() {
$('#addTimePage').addClass('pt-page-moveToRightEasing pt-page-ontop');
$('#timePage').addClass('pt-page-moveFromLeft pt-page-current');
setTimeout(function () {
$('#timePage').removeClass('pt-page-moveFromLeft');
$('#addTimePage').removeClass('pt-page-moveToRightEasing pt-page-ontop pt-page-current');
}, 400);
});
});
edit: I have setup a simple fiddle of the problem.
Okay, so I noticed a few problems:
Your first .click() call was targeting ALL time-form fieldsets when it should have only been targeting input fields.
Your .change() and second .click() are called inside the first .click() meaning the new methods will be called multiple times (because each use of .click() and .change() adds on to the actual event.
Your submit button wasn't actually submitting anything. It was just hiding itself.
To fix this, I gave each fieldset a class name of .fieldset-time so they can easily be looped through. I added an onclick() event to each <fieldset> to easily manipulate the one (and its children) that was clicked.
Here's the new JavaScript code:
// invoked each time an input with the onclick() attribute is clicked
function editTime(obj) {
$("#addTimePage").fadeIn();
$(obj).attr("id", "active"); // set id to active so we know this is the one we want to change
}
$("#submit").click(function() {
// get the new beginning and end times set by the user
var newBeginTime = $("#add-time input[name=begin_time]").val();
var newEndTime = $("#add-time input[name=end_time]").val();
// loop through all elements with class .fieldset-time and find the active one
$(".fieldset-time").each(function() {
if ($(this).attr("id") == "active") {
$(this).attr("id", "");
$("input[name=begin-time]", this).val(newBeginTime);
$("input[name=end-time]", this).val(newEndTime);
return false; // break out of the .each() loop
}
});
// finally, clear and hide the add time box
$("#add-time input[name=begin_time], #add-time input[name=end_time]").val("");
$("#addTimePage").fadeOut();
});
And the new JSFiddle: http://jsfiddle.net/J4Hjf/7/
I hope that's what you were looking for. :)

Categories