How do I check if Dropdown List is readonly? - javascript

I want to check if a dropdown list is readonly. I have this dropdown on my xpage inside repeat control and based on certain condition one of my dropdown will be in readonly. I want to check which one is in readonly using CSJS (javascript, jquery, dojo)

you can using jquery with few ways:
1st Way:
if($('select').attr('disabled'))
{
alert("read only");
}
Fiddle Example
2nd way:
if($('select').is(':disabled'))
{
alert("read only");
}
3rd way:
if($('select').attr('readonly'))
{
alert("read only");
}

Assuming that your dropdown is an XPages control of type xp:combobox, you can do the following to check if the control is readonly using server-side logic:
getComponent("<id of combobox>").isReadonly()
As you mention yourself, a readonly combobox in XPages is not rendered as a dropdown but as a table with an id of your combobox.

Try with this with jQuery methods:
alert($('select[readonly]').attr('id'));
// alerts the id of readonly select element
if there are multiple readonly select elements then you can store the ids in an array with .map() method:
var readOnly = $('select[readonly]').map(function(){
return this.id;
}).get();
Demo # fiddle with readonly attribute.
or if you meant for disabled then you can change to this script:
alert($('select[disabled]').attr('id'));
or
var readOnly = $('select[disabled]').map(function(){
return this.id;
}).get();

As we know a readonly combobox in XPages is not rendered as a dropdown but as a table with an id of combobox.
If we try to set some values to the readonly dropdown it wont be visible as the readonly dropdown gets rendered as table and that table has value property.
So, I created a span element on runtime for showing my readonly combobox value with the id of my combobox and used visible property of dropdown instead of readonly property so that even table doesn't gets created.
function setValues()
{
//START OF CODE: Set values on dialog
var RepID = "#{id:repeatControlID}"
var totalcont = "#{javascript:getComponent('repeatControlID').getRowCount()}";
var val = "#{javascript: DataSourceObj.getItemValue('docField')}"
for(i=0;i<val.length;i++)
{
var idChL = RepID+":"+i+":comboboxID";
var cbCell = RepID+":"+i+":cbCell"; //cbCell is my id of table cell in which my combobox is present
var element = document.getElementById(idChL);
if(element) //Check if dropdown is rendered, if not then create element on fly
{
element.value = val;
}
else{
createEle(idChL,cbCell,val);
}
}
//END OF CODE: Set values on dialog
}
function createEle(idText,cbCell,idVal)
{
var input = document.createElement("span");
input.innerText = idVal;
input.id = idText;
var parentEle = document.getElementById(cbCell);
parentEle.appendChild(input);
}

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

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.

Getting non-existing ids of textarea on each function of javascript?

I have created user form dynamically in which all input and textarea controls are getting created dynamically. Here in below code, i am trying to fetch the ids of all input and textarea of particular form and in case of input, getting right values but getting wrong values for textarea.
$('#Detailcontact input, textarea').each(function() {
arr[i++] = this.id;
});
Only one textarea is on form, but this function returns multiple non-existing ids of textarea.
You need to do:
$('#Detailcontact input, #Detailcontact textarea').each(function() {
arr[i++] = this.id;
});
Or use .find instead.
$('#Detailcontact').find('input,textarea').each(function() {
arr[i++] = this.id;
});
You could also do with:
$('input,textarea', '#Detailcontact').each(function() {
arr[i++] = this.id;
});

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

add and remove a certain value from a text field

each checkbox that i check, i fill the input with it's id
now, how can i retrieve this id that i put inside the input if the user uncheck the checkbox?
exp:
estate SC,SP was checked;
input recieve SC,SP value in this format = SC,SP
but the user uncheck the checkbox with SC value, then SC should be removed from the input.
this is what i'm doing to fill the input with the checkboxes.
var separador = ",";
var estadosS = "";
$(".checkboxEstados").live("click", function(){
if($(this).is(":checked")){
estadosS += (estadosS == "") ? "" : separador;
estadosS += $(this).attr("id");
$("#holdEstados").val(estadosS);
}else{
// now i'm just cleaning all the input,
// but i need to clean only the checkbox that was unchecked
$("#holdEstados").val("");
}
});
dont know if i was clear, any question, be my guest.
Thanks.
An easy way to solve this is to avoid parsing and removing parts of the data. Instead of trying to remove 'SC', instead regenerate the entire contents of the text field each time any checkbox is selected.
When a checkbox click event is detected, deleted the contents of the text input field, scan all of the selected checkboxes, and include their IDs in the text input field.
You're logic can be greatly simplified. Simply grab each checkbox that is checked when the click event fires:
$(".checkboxEstados").live("click", function() {
var aryIds = new Array();
$(".checkboxEstados:checked").each(function() {
aryIds.push($(this).attr("id"));
});
$("#holdEstados").val(aryIds.toString());
});
Here's a working fiddle.
I would store the value in an array and add and remove values from it and then write the array to the output instead of trying to parse the text each time:
var estadosS = [];
$(".checkboxEstados").live("click", function(){
var index;
if($(this).is(":checked")){
// append the id to the list
estadosS.push($(this).attr("id"));
}else{
index = estadosS.indexOf($(this).attr("id"));
if(index > -1) {
estadosS.splice(index, 1);
}
}
$("#holdEstados").val(estadosS.join(separador));
});
If all you are aiming to do is get a list of the checked values from all the check boxes, you could do:
$('.checkboxEstados:checked').each(function(){
alert($(this).val());
});
And that should return all the check box items that have been checked. Then you don't have to worry about adding and removing data from a text box. I'm just alerting the value, you would want to store them into an object or something more useful.

Categories