I have many inputs where to dynamically change the value of the name attribute, for example:
Select
<select class="form__input form__select select optional" id="js-customer-field" name="customer[customer_food_attributes][16321232322354][customer_id]"><option value="">Select</option>
...
<select class="form__input form__select select optional" id="js-customer-field" name="customer[customer_food_attributes][023912321331123][customer_id]"><option value="">Select</option>
I would like to take the value to apply to an event, but since the id's are random I don't know how to capture them
on this name attribute or any with random id:
"customer[customer_food_attributes][023912321331123][customer_id]"
$("customer[customer_food_attributes][023912321331123][customer_id]").on('change'), function(e, item) {...})
I would be very grateful if someone could help me build the attribute dynamically
Thank you for your time in reading me.
It is not really clear to what you are trying to do. Could you maybe clarefy a little bit?
Are you trying to change the name attribute of the select elements?
Or do you want to bind an event to all select elements?
If the latter, I would do something like this (assuming you want to trigger the event on a value change):
$(".form__select").on("change", function(){
// Get the name attribute
let name = $(this).attr("name");
// Do whatever you like, depending on the value of name
// ...
};
You could just listen to change events from any select elements and check if the name matches the pattern.
This can be done with/without jQuery.
// using jquery
$('select').on('change', function(e) {
const regex = /customer\[customer_food_attributes\]\[(\d+)\]\[customer_id\]/;
const match = e.target.name.match(regex);
if(match){
const id = match[1];
// here is your id
// do something with it
}
});
// using vanilla js
document.addEventListener('change', function(e) {
const regex = /customer\[customer_food_attributes\]\[(\d+)\]\[customer_id\]/;
const match = e.target.name.match(regex);
if(match){
const id = match[1];
// here is your id
// do something with it
}
});
Related
I am new into javascript, and I've been working on this "project", but I need some help because I'm stuck. I might've not expressed my self correctly in the title so here it is:
I would like to get the ID of an option element (<select> <option id="#"> </select>) by using the "change" event listener on the <select>. So when I choose for example "Action" from the select dropdown, I'd like that change to trigger a function that will get that element's ID and use it in a function down below. Here's the code that I have so far, which basically does the following:
1.) Gets the genre list;
2.) Then for every item in the response.data.genres, sets a number which corresponds to the length of the array (total 19 items).
3.) If the selected "option" element matches the name of the genre in the array, then it defines the genre ID(the integer) and makes another request to the API in order to list the movies matching that genres ID. Thanks in advance.
//Genres
function genres(){
//API request.
axios.get("https://api.themoviedb.org/3/genre/movie/list?api_key=<API_KEY>&language=en-US")
.then((response)=>{
//console.log(response);
let genres = response.data.genres;
genres.length;
console.log(genres)
for(var i = 0; i < genres.length; i++){
var genresId = response.data.genres[i];
var tag = document.getElementById("Thriller");
console.log(genresId);
if(tag.id === genresId.name){
let genre = genresId.id;
axios.get("https://api.themoviedb.org/3/discover/movie?api_key=<API_KEY>&language=en-US&sort_by=popularity.desc&include_adult=false&include_video=false&page=1&with_genres="+genre)
.then((response)=>{
console.log(response);
})
}
}
})
}
So there are two steps if I understand correctly.
1. get the list of genres and fill a selectbox with it.
2. get a list of movies if an option in the selectbox is selected.
The first step, you can do with an innerHTML method. For every genre that is returned, you build a string like <option value='genre'>genre</option>. With innerHTML you add these options to the select box. The value property is what you use to see which option is selected.
Next we add an eventlistener to the dropbox so our script will react to the changes the user makes. The event we're listening for is 'change' and it will trigger the function 'getMovies'. See Mozilla docs for more info. event.target.value will give you the value of the selected option, which you can use as genre id.
Inside this function you will do your second api call to get your movie list.
A simple example without the api calls is this:
let genreDropdown = document.getElementById('genre');
genreDropdown.innerHTML = getGenres();
genreDropdown.addEventListener("change", getMovies);
function getGenres(){
let genres = ['action', 'romcom', 'thriller']; //this would be replaced with the api call to get the genres
let innerHtml = '';
for(var i = 0; i < genres.length; i++){
var option = '<option value='+genres[i]+'>'+genres[i]+'</option>';
innerHtml += option;
}
return innerHtml;
}
function getMovies(event) {
let genre = event.target.value;
alert(genre) //you can replace this with the api call to get the movies.
}
<select id='genre'>
<option>loading...</option>
</select>
The following Code will look for a <select> (its id to be exact) Element and on change it will output the ID of the Direct Child (<option> in this case).
$(document).ready(function(){
$("#myDropdown").on("change", function(){
the_id = $(this).children(":selected").attr("id")
$("#output").html(the_id);
});
});
I have made an Example for you > JS Fiddle
Hope you can use the jQuery Code.
I am creating a form builder script. I have a select input where the user can select the form element they want to use, depending on their selection ("select", "checkbox" or "radio") another form field is displayed allowing users to input their options.
Users can create as many instances of form elements as they want, so each select input has a dynamically created id that corresponds to the id of the hidden form field. I then use jQuery to determine whether the "options" field should be hidden or not (triggered on change of the form elements select input).
Currently, for every instance, I have the following code addedabove the select input:
<script>
jQuery(document).ready(function($) {
var arr = ['select', 'checkbox', 'radio'];
var thisForm = 'select.input-type-118';
function showHideSelect() {
var val = $(thisForm + ' option:selected').val();
var selectOptions = $('#select-options-118')
if (arr.indexOf(val) >= 0) {
selectOptions.show();
} else {
selectOptions.hide();
}
}
showHideSelect();
$(thisForm).change(function() {
showHideSelect();
});
});
</script>
Where var thisForm and var selectOptions are added dynamically and refer to the select option below this script.
I'm wondering if there is a better way to do this rather than repeat several instances of this, at the moment, a users page cold look like this:
<script>
...
</script>
<select>
...
</select>
<textarea>
This is hidden depending on the select option
</textarea>
<script>
...
</script>
<select>
...
</select>
<textarea>
This is hidden depending on the select option
</textarea>
<script>
...
</script>
<select>
...
</select>
<textarea>
This is hidden depending on the select option
</textarea>
...etc...etc
My concern is that I don't think it's best practice to have so many instances of the same script, but I'm unsure how to write a global script that will allow me to show/hide the textarea on an individual basis.
I have shown a more accurate depiction of my workings on this jsfiddle here:
https://jsfiddle.net/46stb05y/4/
You can use Event Delegation Concepts. https://learn.jquery.com/events/event-delegation/
With this you can change your code to
$(document).on('change','select',function() { //common to all your select items
showHideSelect($(this)); // passing the select element which trigerred the change event
});
This will work even on the select items that are added dynamically
You must change your function to receive the element as the parameter.
function showHideSelect($selectElement) {
var val = $selectElement.val();
var selectOptionsId = $selectElement.attr('class').replace('input-type','select-options');
var selectOptions = $("#"+selectOptionsId);
if (arr.indexOf(val) >= 0) {
selectOptions.show();
} else {
selectOptions.hide();
}
}
Here is the Working JsFiddle
<input type="checkbox" onfocus="EnsureSelectionHandlerOnFocus(event,this,12)" onclick="ToggleAllItems(event,this,12)" title="Select or deselect all items" class="s4-selectAllCbx">
Whenever I refresh the page, these attributes have been changed with "12" in both EnsureSelectionHandlerOnFocus and ToggleAllItems. Therefore, I would like to get "12" of the onfocus and set "12" to the onlick attribute with Javascript?
If I understand you correct, you want to extract the number - the last param of the inline event listeners?
//get the event, example EnsureSelectionHandlerOnFocus(event,this,12)
var event = document.getElementById('cbSelectAll').getAttribute('onfocus');
//extract the params, example event,this,12
var params = event.match(/\(([^)]+)\)/)[1];
//get the last param, example 12
var number = params.split(',')[2];
//outputs 12
console.log(number);
To set the onclick event number param :
var click = 'ToggleAllItems(event, this, NUMBER)';
click = click.replace('NUMBER', number);
document.getElementById('cbSelectAll').setAttribute('onclick', click);
Example alternatives to document.getElementById
//selecting the checkbox by its class (if the class is unique)
var element = document.querySelector('.s4-selectAllCbx');
console.log(element);
//alternatively selecting the checkbox by an attribute
var element = document.querySelector('[title="Select or deselect all items"]');
console.log(element);
or add an unique name to the checkbox :
<input type="checkbox" name="myCheckBox" ...>
var element = document.querySelector('[name="myCheckBox"]');
console.log(element);
both will return the checkbox. If multiple elements has the same class or the same attribute, the first occurrence in the document will be returned. Giving the checkbox an unique class is prefered, imho, since you will have to update your code each time you change the attribute of the title.
I have some code that loops over each row of the table and creates a json object. The elements in the rows can be either of the following:
<input type="text" id="myelem"/>
or
<p id="myelem">foo</p>
Notice that the id attribute for the both is same. This is because on the table there is a button Add a new Row when this button is clicked another row is added to the table with a checkbox. When user submits the form the checkbox goes away and the value they entered turns into <p id="myelem">value they entered</p>
Below is the code I'm using for this.
$('.input-row').each(function(index, row) {
var innerObject = {};
var key = $('#myelem', row).val().toUpperCase();
jsonObject[key] = "bar";
});
The above works fine for textboxes becuse I'm using the .val() function. However, how do I get the data from the row if it contains <p id="myelem">foo</p> ??
my pseudo code would be something like this:
$('.input-row').each(function(index, row) {
var innerObject = {};
/*
if #myelem is a text box then use .val()
if #myelem is a <p> tag then use .html()
*/
var key = $('#myelem', row).val().toUpperCase();
jsonObject[key] = "bar";
});
ids should always be globally unique on a page. If you need multiple elements to be referenced, you should use classes. If you set myelem as a class rather than an id you could then reference it like this
$('.input-row .myelem')
You can check which type the element is with
var value = null;
if($('#myid').is('input')) {
value = $('#myid').val();
}
else if($('#myid').is('p')) {
value = $('#myid').html();
}
IDs are unique. You cannot use more than one ID in the same page. If you do so how should you decide which element to use?
You could use jQuery is() eg if $('#myelem').is ('p'){...}
If still want to stick your development way then below might help you:
$('.input-row').each(function(index, row) {
var innerObject = {};
var c = $('#myelem', row);
var isInputField = c.get(0).tagName.toUpperCase()=="INPUT";
var key =isInputField ? c.val().toUpperCase():c.html().toUpperCase();
jsonObject[key] = "bar";
});
This is to just get you started. You are using .each on class input-row but you have not shown the class in your code that you provided. I have used class instead of id in this example. Use it to work ahead.
Fiddle
I need to be able to change certain option from select menu to be as default (start) value when I do something.
For example when I declare it, English language is default value.
How to change that with the code and not with the click.
<form id="form1" name="form1" method="post" action="">
<select name="websites1" id="websites1" style="width:120px" tabindex="1">
<option value="english" selected="selected" title="images/us.gif">English</option>
<option value="espanol" title="images/es.gif">Espanol</option>
<option value="italian" title="images/it.gif">Italiano</option>
</select>
</form>
In the body tag I have declared:
<script type="text/javascript">
$(document).ready(function() {
$("body select").msDropDown();
});
</script>
I am using this SCRIPT
I have tried all of the bellow examples and none this is good for me.
What else can I do change default select value.
This is working for me as mentioned in the docs:
$('#websites1').msDropDown().data('dd').set('selectedIndex',2);
This will select italian ;)
/edit:
Keep in mind that #Patrick M has a more advanced approach and he posted his approach before I posted mine ;)
If you are having weird css issues like I did, try this undocumented stuff:
$('#websites1_msa_2').click(); // this will also select the italian
As you can see the id is generated by $('#websites1_msa_2') the id of the selectbox plus the $('#websites1_msa_2') index of the option item.
A bit hacky but works ;)
So you could then define a JavaScript-Function like this:
var jQueryImageDD_selectByName = function(name) {
var children = $('#websites2_child').children();
for(var i=0;i<children.length;i++) {
var label = children[i].getElementsByTagName('span')[0].innerHTML;
if(label === name) {
children[i].click()
}
}
};
And then use it like this:
jQueryImageDD_selectByName('Italiano'); // will select Italiano :)
He does say
You can set almost all properties via object
So, just guessing from the documentation examples he provides on that page... I would think adapting this:
var oHandler = $('#comboboxid').msDropDown().data("dd");
oHandler.size([true|false]);
//Set or get the size property
To the .value property might work. So for you to set the language to Italian, try
var oHandler = $('#comboboxid').msDropDown().data("dd");
oHandler.value('italian');
// Or maybe the way to do it is this:
oHandler.set('value', 'italian');
// Or maybe 'value' shouldn't be in single quotes
//set property
If that doesn't work, you could try looping over all the properties, getting and comparing the value at each index and, when you find it, setting the selected index to that property name.
var languageSelect = $('websites1');
var oHandler = $('#websites1').msDropDown().data("dd");
for(var index = 0; index < languageSelect.length; index++) {
var option = oHandler.item([index]);
if(option == 'italian') {
oHandler.set("selectedIndex", index);
break;
}
}
One of those should work. If not, you're pretty much just going to have to wait for a reply from the author.
You can either use selectedIndex to change the index of the selected option (0 being the first)
document.getElementById("websites1").selectedIndex = 1; //espanol
, or you can use value to change the text of the value (and if there's a match, it will change it automatically).
document.getElementById("websites1").value = 'espanol';
use selectedIndex. See this page. A select control has an options property, which basically is an array of option elements. The first element in your select is options[0], english, so:
document.getElementById("websites1").selectedIndex = 0; //=> english
You can also make the first option selected by default using:
document.getElementById("websites1").options[0]
.defaultSelected = true; //=> english by default
working option (1. destroy msdropdown, 2. select by value, 3. set up msdropdown)
put this code somewhere in js:
jQuery.fn.extend({
setValue: function(value) {
var dd = $(this).msDropdown().data("dd");
dd.destroy();
$(this).val(value);
$(this).msDropdown();
}
});
setting value:
$('#selectorOfmsDropDown').setValue('opt10');
or just:
$("#selector").msDropdown().data("dd").setIndexByValue(newvalue);