Checking g-select mapping properties - javascript

Hello I created this dropdownbox
<g:select from="${[['key':1, 'value':'text1'],['key':2, 'value':'text2' else']]}" optionKey="key" optionValue="value" name="mine"/>
My question is how can I print the message "hi" everytime I have clicked on the text1 field

For the select you can use attribute onchange to set the function it will call when value is changed:
<g:select onchange="printmsg(this)" from="${[['key':1, 'value':'text1']....
Then you write that function that checks the new value for the select and determines if it is what you are looking for.
printmsg = function(element) {
var chosen = $(element).val();
if (chosen === "text1"){
alert("Omg. What have you done?!");
}
}
Of course put Javascript in gsp page (and for this code add jquery library) as well.

Related

jQuery change element on select - global script for multiple select inputs

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

JS variable to HTML elements and vice versa

In the beginning I have JSON data, and I need to convert and output the list to html.
var frut =
{
"wtfrut": [
["0x01", "Apple"],
["0x02", "Orange"],
["0x03", "Pineapple"],
["0x04", "Banana"]
],
[other irrelevant elements]
}
I made it an html <select> plus list of <options> . . .
<select>
<option data-index="0x01">Apple</option>
<option data-index="0x02">Orange</option>
<option data-index="0x03">Pineapple</option>
<option data-index="0x04">Banana</option>
</select>
. . . and stuck it in a js variable.
This <select> list is a cell in a table, and needs to appear in a couple hundred rows.
While building the table, when I need to display the dropdown, I need to go back thru and find the selected attribute of each <select><option>
Problem 1)
The best I can get from
var select = document.createElement("select");
var options = document.createElement("option");
options.setAttribute("value", element[1]);
...
select.appendChild(options);
return select;
is [object HTMLSelectElement] where the dropdown was supposed to be. return select.value returns the value attribute of the first item on the list.
Therefore, I have resorted to stuffing var dropDown with raw html.
out += "<option value=\"" + element[1] + "\" data-hex = \"" + element[0] + "\" data-index = \"" + index + "\">";
because it works. dropDown winds up with the <select> and all <option>s. And it works when I call it with
"<td class=\"vkeyName\" data-f4key-index = \"+index+\">" + dropDown + "</td>"
Problem 2)
Now that that's working, I try to take dropDown back to js at render time (during the loop that produces the above <td>) and figure out which <option> needs to be chosen as default for the dropdown. select.length returns the string length which I understand. It's just a js string.
Overall
What I don't understand is how to get data over the threshold between js variable and valid html element, in either direction. To make that js string into a list of valid html elements that can be output to the html page... Or to take valid html elements, put them into a variable to be worked by js.
getElementBy* and document.write doesn't work. I presume because I don't have the document yet, I'm building objects.
At this point I'm uninterested in js libraries and helpers. This is a learning project and I want to understand this so that things like jQuery aren't so magical.
I made a small example of a way how you could do create a combobox that generates an Array of some kind of data, and how you could help out yourself by using some callback functions to get the value and the text, and how to choose which element should be preselected, and how you could react on changes in the html element.
You can always use document.getElementById, but you have to wait until you are sure that the page got loaded, one way to do it, is to wait for the window.onload function to fire (which means that the DOM is ready to be manipulated, scripts and css are loaded)
In vanilla javascript, you can do it by registering a callback function on the load event, like this:
window.addEventListener('load', function() { ... });
To generate the combobox, I made a small helper namespace and added a comboBoxGenerator, that takes an object in, and generates the combobox in your desired targetElement.
I then iterate the data and for each element, get the value and text over a callback function (that you define when you called the generator) and it returns the value and the text for that single option. It also determines if the element should be preselected.
By registering to the change event of the combobox, you can then find out which element was actually selected, and for that I also added a small function that displays that the function got changed
The 'use strict;' statement helps to add for example forEach function to the array, and will help you to keep your code more clean
I also documented the source a bit, so that you hopefully understand what everything is doing :)
'use strict';
var helper = {};
(function(ns) {
function comboBoxGenerator(options) {
// get the element that you are targetting
var el = document.getElementById(options.target),
cmb = document.createElement('select'),
option;
// iterate the data, and for each element in the array, create an option and call the defined callback functions
options.data.forEach(function(item) {
option = document.createElement('option');
option.value = options.valueSelector(item);
option.text = options.textSelector(item);
option.selected = options.isSelected(item);
// add the option to the combobox
cmb.appendChild(option);
});
// listen to changes on the combobox and then call the selectionChanged event
cmb.addEventListener('change', function(e) {
// this = cmb because of the bind statement on below
// call the selectionChanged callback function, and assing the cmb as the this for the callback function (.apply(this, ...))
options.selectionChanged.apply(this, [this.options[this.selectedIndex]]);
}.bind(cmb));
el.appendChild(cmb);
}
// set the combo function on the helper by either reusing an existing function, or the function just written above
ns.combo = ns.combo || comboBoxGenerator;
}(helper));
// wait till all resources are loaded, and then generate the combobox
window.addEventListener('load', function() {
var dummyData = {
"wtfrut": [
["0x01", "Apple"],
["0x02", "Orange"],
["0x03", "Pineapple"],
["0x04", "Banana"]
]
}, selectedValue = "0x03";
// call the helper method with an object defining the data, targetelement, and callback functions
helper.combo({
target: 'myTable',
data: dummyData.wtfrut,
valueSelector: function(item) {
// item would be like ["0x01", "Apple"], return "0x01" for value
return item[0];
},
textSelector: function(item) {
return item[1];
},
isSelected: function(item) {
// check if the item matches a selectedValue if so, return true, not false
return item[0] === selectedValue;
},
selectionChanged: function(item) {
// gets called when the selection is changed, item = Option, value is the current value, this = combobox
selectedValue = item.value;
console.log('selectedValue changed to ' + selectedValue + ' index = ' + this.selectedIndex);
}
});
});
<div>
<div id="myTable">
</div>
</div>

How to get another html tag value using this property

I have a buttton inside a table.
<input type="button" onclick="I_Have('IS-12-78',this)" class="i_have_it" value="Yes, I have">
When I click the button I need to get the value of select box in the same row.
I haven't maintained separate class or id for this select box.
function I_Have(itm_id,obj)
{
xmlReq=new XMLHttpRequest();
xmlReq.open("POST","./requests/store.jsp",false);
xmlReq.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlReq.send("item="+itm_id+"&wt=1");
if(xmlReq.responseText.trim()!="")
{
alert(xmlReq.responseText)
obj.style.display="none"
return false
}
//obj.innerHTML("Used")
obj.setAttribute('onclick','I_Dont_Have("'+itm_id+'",this)')
obj.setAttribute('value','No, I dont have')
obj.setAttribute('class','i_dont_have_it')
}
Using "this"(passed into the function) property can I get the value of select box in javascript.
You can use Dom object's previousElementSibling property:
this.previousElementSibling.value
Have a look on this fiddle.
But this will only work if select is immediate sibling of your button element.
If that's not your case then first get the parent element then reach to your required element:
window.callback = function(obj){
var parent = obj.parentElement;
// Uncomment following to get value from nearest <TD> if your htmls is structured in table
//parent = parent.parentElement;
var select = parent.getElementsByTagName('select')[0];
alert(select.value);
}
Here is updated fiddle.

Unable to get value of input field, even through text() and val() methods

I want to get the value of an input field that a user will type into, then do things with it. I've tried the two ways to get value , text() and val(), on the input fields, but neither work.
Kindly advise on what it could be that I'm missing here.
What happens exactly in the code below is that after hovering a button, the value of an input field would be shown through an alert() function. But the alert is constantly blank.
HTML
<div id="collection_name">
collection name
</div>
<input type="text" id="collection_title" placeholder="Midnight in New York">
<div id="collection_button"></div>
jQuery
var collection_title = $('#collection_title').text();
var collection_button = $('#collection_button');
collection_button.on({
mouseover: function() {
alert(collection_title); // the alert comes out blank
}
});
You need to call the text()/val() methods within the handler itself
var collection_title = $('#collection_title');
var collection_button = $('#collection_button');
collection_button.on({
mouseover: function() {
alert(collection_title.val()); //or .text() depending on the element type
}
});
The reason it was blank before is at the time of initializing
var collection_title = $('#collection_title').text();
it had no text value
Demo Fiddle
var collection_title = $('#collection_name').text();
var collection_button = $('#collection_button');
collection_button.on({
mouseover: function () {
alert(collection_title); // the alert comes out blank
}
});

How to differentiate between DOM elements in jQuery

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

Categories