I using Datatable library to show a table in wordpress custom plugin where I need to return selectbox input. The select box option should display the option as it is saved in database but it is showing the first option always.
How to code the same thing in js when the select input is returned for a column in datatable. I have tried the following way:
columns: [{
{
'data': null,
'render': function (data, type, row, meta) {
return '<select class="selectpicker" name="pm" id="pm-' + row.mls + '"><option value="Tafolla">Tafolla</option><option value="Lucy">Lucy</option></select>';
}
},
}]
Well first get the JS value that is selected then based off return call the php value in a separate call not inlineHTML . Try not overcomplicate cross language calls ...
document.getElementById('my-select').addEventListener('change', function() {
console.log('You selected: ', this.value);
//Call PHP values based on selection e.g
if(this.value == 2)
{
var text = " <?php echo ($row['status'] == 'AR')?'selected='selected':''; ?>";
}
});
<select id="my-select">
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
The other way of doing it is in plain php with HTML select
<select name="formGender">
<option value="">Select...</option>
<option value="M">Male</option>
<option value="F">Female</option>
</select>
//PHP
<?php
if(isset($_POST['formSubmit']) )
{
$varGender = $_POST['formGender'];
}
?>
So i have this SELECT tags here
<select id="url">
<option id="url1" >url 1</option>
<option id="url2" >url 2</option>
</select>
<button onclick="go()">GO</button>
Then a script here
<script>
function go() {
$.ajax({
url: 'url1.php?check=' + value,
type: 'GET',
async: true,
})
Now, I want to change the line of code that says: url: 'url1.php?check=' + value, to say whatever the selected option's id is rather than the hardcoded "ur1.php". How do I achieve these?
NOTE: I cut the code if you're wondering why is it like that.
Here's a working demo of what you need. I changed the following to make it work:
1) give your <option> tags value attributes (as per documentation) rather than ids. The one relating to the chosen option is then automatically read as being the value of the <select>.
2) get the currently selected URL value by using .val() to get the value of the <select>
3) (non-essential but good practice) using an unobtrusive event handler in the script itself rather than an inline "onclick".
4) (non-essential) you don't need async:true because that's already the default value.
var value = "something";
$("#go").click(function() {
var url = $("#url").val() + '.php?check=' + value;
console.log(url);
$.ajax({
url: url,
type: 'GET',
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="url">
<option value="url1">url 1</option>
<option value="url2">url 2</option>
</select>
<button type="button" id="go">GO</button>
The proper way to do this is to give each of your option's a value attribute. You can the get the select-element and get it's value (which will be the value of the selected option)
I added some code to help you:
function go() {
const select = document.getElementById('select');
const value = select.value; // <-- this here is the value you can use to make your request
console.log(value);
}
<select id="select">
<option value="url1">URL 1</option>
<option value="url2">URL 2</option>
</select>
<button onclick="go()">Go</button>
HTML Code:
<SELECT id="url">
<option id="url1" >url 1</option>
<option id="url2" >url 2</option>
</SELECT>
<button id = "button_go">GO</button>
Script:
$("#button_go").click(go);
function go() {
var value =$('#url').children("option:selected").attr('id');
alert("You have selected the ID- " + value);
// your ajax code
}
Check the jsfiddle working code : https://jsfiddle.net/1eq29w6a/4/
So to continue my last question (link). I've finally got that sorted out (with help), but now the value of the name is only the first value of the drop down list.
A brief explanation, I have 2 drop down menu's and when you select a option from one (A) the other drop down menu is updated (B). I know it has something to do with an array but I can't figure this out.
Here are my files.
HTML
<select id="main_cat" name="main_cat">
<option selected="-1" select="selected">Select something</option>
<?php
$sttub = str_replace('&', 'en', $stub);
$q = $row["Categorie"];
echo "
<option class='dropdownmenu_A' value='".$sttub."' name='".$q."'>"
.$row["Categorie"]."
<span style='font-size:1.2rem;color:#F8F8F8;'>
(" . $row['x'] . ")
</span>
</option>
";
}}?>
</select>
<select name="sub_cat" id="sub_cat" disabled="disabled"></select>
JavaScript
$(function(){
$('#main_cat').change(function(){
var $mainCat=$('#main_cat').val();
var $mainName = $(".dropdownmenu_A").attr("name");
// call ajax
$("#sub_cat").empty();
$.ajax({
url:"<?php bloginfo('wpurl'); ?>/wp-admin/admin-ajax.php",
type:'POST',
data:'action=my_special_ajax_call&main_catid=' + $mainCat + '&main_name=' + $mainName,
success:function(results)
{
// alert(results);
console.log($mainCat,$mainName);
$("#sub_cat").removeAttr("disabled");
$("#sub_cat").append(results);
}
});
}
);
});
function.php
function implement_ajax() {
if(isset($_POST['main_catid']))
{
$q = $_POST['main_catid'];
$x = $_POST['main_name'];
echo '<option value="-1" selected="selected">'.$x.'</option>'.$option;
die();
} // end if
}
I have tried using <select id="main_cat" name="main_cat[]"> like I found on google but this didn't work. Using $x[] = $_POST['main_name']; just echos the word Array. How do I get this to work and display the correct option that is selected and not just the first every time.
To be clear, here are my drop down menu's (sometimes my brain goes faster then I can type, so I hope it's clear).
select{height:30px}
<select id="main_cat" name="main_cat">
<option selected="-1" select="selected">Select something</option>
<option class='dropdownmenu_A' value='option-1' name='Option 1'>
<option class='dropdownmenu_A' value='option-2' name='Option 2'>
<option class='dropdownmenu_A' value='option-2' name='Option 2'>
</select>
<select id="sub_cat" name="sub_cat">
<option selected="-1" select="selected">Select something</option>
<option class='dropdownmenu_B' value='sub-option-1' name='Sub Option 1'>
<option class='dropdownmenu_B' value='sub-option-2' name='Sub Option 2'>
<option class='dropdownmenu_B' value='sub-option-2' name='Sub Option 2'>
</select>
So right now if I select Option 1 from dropdownmenu_A it only echo's the first value from dropdownmenu_A to dropdownmenu_B and not Option 2 or Option 3.
1- You can't have <span/> tags inside <option/> tags as the latter cannot have any child elements.
2- <option/> doesn't have a name attribute. If you want to create a custom attribute, use HTML5 data attributes. That's what they are for.
3- printf is your new friend.
printf('<option class="dropdownmenu_A" value="%s" data-name="%s">%s (%s)</option>', $sttub, $q, $row["Categorie"], $row['x']);
4- I believe the problem is $(".dropdownmenu_A").attr("name") as this would always pull the same name and not the selected name. In your particular case, I would do
$(function(){
$('#main_cat').change(function(){
var $option = $(this).find('option:selected'),
id = $option.val(),
name = $option.data('name');
// open your browser's console log and ensure that you get the correct values
console.log(id, name);
$("#sub_cat").empty();
// call ajax
$.ajax({
url: "<?php bloginfo('wpurl'); ?>/wp-admin/admin-ajax.php",
type:'POST',
data: {
action: 'my_special_ajax_call',
main_catid: id,
main_name: name
},
success: function (results) {
$("#sub_cat").removeAttr('disabled').html(results);
}
});
});
});
You should add a selected attribute to your selected option:
https://www.w3schools.com/tags/att_option_selected.asp
With a Handlebars.js template like this...
<select>
<option value="Completed">Completed</option>
<option value="OverDue">OverDue</option>
<option value="SentToPayer">SentToPayer</option>
<option value="None">None</option>
</select>
... and data like this...
{
"id" : 1,
"name" : "World"
"status" : "OverDue",
"date" : "2012-12-21"
}
I want to render HTML like this.
<select>
<option value="Completed">Completed</option>
<option value="OverDue" selected="selected">OverDue</option>
<option value="SentToPayer">SentToPayer</option>
<option value="None">None</option>
</select>
Which way is the easiest?
I found a lot of over complicated solutions and decided to write my own using a Handlebars helper.
With this partial (using Jquery) ...
window.Handlebars.registerHelper('select', function( value, options ){
var $el = $('<select />').html( options.fn(this) );
$el.find('[value="' + value + '"]').attr({'selected':'selected'});
return $el.html();
});
You can wrap selects in your Handlebars template with {{#select status}}...
<select>
{{#select status}}
<option value="Completed">Completed</option>
<option value="OverDue">OverDue</option>
<option value="SentToPayer">SentToPayer</option>
<option value="None">None</option>
{{/select}}
</select>
and end up with this...
<select>
<option value="Completed">Completed</option>
<option value="OverDue" selected="selected">OverDue</option>
<option value="SentToPayer">SentToPayer</option>
<option value="None">None</option>
</select>
Presto!
I just had a similar need as the OP--with a static set of select options, but a dynamic selected value. I really like #janjarfalk's solution, but I'm using node.js and don't have jQuery pulled in. So, I put together my own variation based on RegExp's. Hope this is helpful to others.
Handlebars helper:
hbs.registerHelper('select', function(selected, options) {
return options.fn(this).replace(
new RegExp(' value=\"' + selected + '\"'),
'$& selected="selected"');
});
Handlebars template:
<select>
{{#select CurrentSort}}
<option value="1">Most Recent First</option>
<option value="2">Most Recent Last</option>
<option value="3">Highest Score First</option>
<option value="4">Highest Score Last</option>
<option value="5">Most Comments</option>
<option value="6">Fewest Comments</option>
<option value="7">Most Helpful Votes</option>
<option value="8">Fewest Helpful Votes</option>
{{/select}}
</select>
You can tweak the helper to work even if you don't use the value attribute--just adjust the regexp to search the element text, and do the string replacement before the matched text.
I saw the extremely clever solution posted by #janjarfalk and realized it didn't work for options defined without a value attribute (such as <option>Value</option>). My application needed that, and I wanted a helper done in vanilla JavaScript for performance, so I came up with the following.
This solution will support <option>Both a label and a value</option> in addition to <option value="aValue">A label</option> and will be much faster as it doesn't use jQuery.
Handlebars.registerHelper('select', function(value, options) {
// Create a select element
var select = document.createElement('select');
// Populate it with the option HTML
select.innerHTML = options.fn(this);
// Set the value
select.value = value;
// Find the selected node, if it exists, add the selected attribute to it
if (select.children[select.selectedIndex])
select.children[select.selectedIndex].setAttribute('selected', 'selected');
return select.innerHTML;
});
Usage:
<select>
{{#select status}}
<option>Option 1</option>
<option>Option 2</option>
<option value="Option 3">Option 3 (extra info)</option>
<option value="Option 4">Option 4 (more extra)</option>
{{/select}}
</select>
Works for me
<select>
<option value="{{status}}" hidden="hidden" selected="selected">{{status}}</option>
<option value="Completed">Completed</option>
<option value="OverDue">OverDue</option>
<option value="SentToPayer">SentToPayer</option>
<option value="None">None</option>
</select>
I've had problems with the "select block" approach when using the "each" helper to build something dynamic, due to the context.
Here is my solution:
Handlebars.registerHelper('option', function(value, label, selectedValue) {
var selectedProperty = value == selectedValue ? 'selected="selected"' : '';
return new Handlebars.SafeString('<option value="' + value + '"' + selectedProperty + '>' + label + "</option>");
});
And the template:
<select>
{{#each status}}
{{option id name ../statusId}}
{{/each}}
</select>
Improved answer of #lazd to select first option when nothing matches.
Handlebars.registerHelper('select', function(value, options) {
// Create a select element
var select = document.createElement('select');
// Populate it with the option HTML
$(select).html(options.fn(this));
//below statement doesn't work in IE9 so used the above one
//select.innerHTML = options.fn(this);
// Set the value
select.value = value;
// Find the selected node, if it exists, add the selected attribute to it
if (select.children[select.selectedIndex]) {
select.children[select.selectedIndex].setAttribute('selected', 'selected');
} else { //select first option if that exists
if (select.children[0]) {
select.children[0].setAttribute('selected', 'selected');
}
}
return select.innerHTML;
});
Usage remains same:
<select>
{{#select status}}
<option>Option 1</option>
<option>Option 2</option>
<option value="Option 3">Option 3 (extra info)</option>
<option value="Option 4">Option 4 (more extra)</option>
{{/select}}
</select>
This might take more code in the template, but it is easier to read:
.js
Handlebars.registerHelper('select', function(selected, option) {
return (selected == option) ? 'selected="selected"' : '';
});
.hbs
<select name="status">
<option value="public" {{{select story.status 'public'}}}>Public</option>
<option value="private" {{{select story.status 'private'}}}>Private</option>
<option value="unpublished" {{{select story.status 'unpublished'}}}>Unpublished</option>
</select>
I prefer to use a template approach. By this I mean the layout of the option tag itself is specified in the handlebars template (where someone might look for it) and not in the javascript helper. Template inside the block helper is passed into the helper script and can be used by calling options.fn() which then uses any script changes you have made in your helper.
Template:
<select>
{{#optionsList aStatusList sCurrentStatusCode 'statusCode'}}
<option {{isSelected}} value="{{statusCode}}">{{statusName}}</option>
{{/optionsList}}
</select>
Slightly modified data (not required but a little more "real world" for me)
var myOrder =
{
"id" : 1,
"name" : "World",
"statusName" : "OverDue", /* status should NOT be here! */
"statusCode" : "1",
"date" : "2012-12-21"
}
var sCurrentStatusCode = myOrder.statusCode;
var aStatusList =
[
{
"statusName" : "Node",
"statusCode" : 0
},
{
"statusName" : "Overdue",
"statusCode" : 1
},
{
"statusName" : "Completed",
"statusCode" : 2
},
{
"statusName" : "Sent to Payer",
"statusCode" : 3
}
]
Javascript registered helper:
Handlebars.registerHelper( 'optionsList',
function ( aOptions, sSelectedOptionValue, sOptionProperty, options )
{
var out = "";
for ( var i = 0, l = aOptions.length; i < l; i++ )
{
aOptions[ i ].isSelected = '';
if( ( sOptionProperty != null && sSelectedOptionValue == aOptions[ i ][ sOptionProperty ] ) || ( sSelectedOptionValue == aOptions[ i ] ) )
{
aOptions[ i ].isSelected = ' selected="selected" ';
}
out = out + options.fn( aOptions[ i ] );
}
return out;
} );
optionsList is what I have chosen to name this helper
aStatusList an array of status objects contain several properties including the status value/name (in most cases I have encountered this would be the status code not the status name that is stored )
sCurrentStatus is the previously selected status code (not the value) and is the option value that i would like to have the selected in this generated option list.
statusCode is the string property name within a aStatusList object that I will test to see if it matches myStatus that is aStutusList[ loopIndex ][statusCode]
the string option property ( statusCode in this case ) is only required for objects -- options lists may also be arrays of strings (instead of objects that in turn containing strings) in which case you may omit the the third property 'statusCode' which tells the helper what property of the object to test agains. If you don't pass that property it will just test againts the list item itself.
if the sSelectedOptionValue is not passed then the list will be produced without setting any item to selected. This will generate the list pretty much the same as using the {{#each}} helper
I just ran into this problem, here's a solution for when the options are dynamic..
Instead of creating a select helper, I created an option helper that accepts the value of the item you wish to be selected.
Handlebars.registerHelper('option', function(value) {
var selected = value.toLowerCase() === (this.toString()).toLowerCase() ? 'selected="selected"' : '';
return '<option value="' + this + '" ' + selected + '>' + this + '</option>';
});
And in my template.
{{#items}}
{{{option ../selected_value}}}
{{/items}}
Please note the ../ to access the parent's scope as it's not likely the selected_value will be inside of the items array.
Cheers.
If you have very few options and you don't want to write a helper, here is what you can do:
//app.js
var data = {selectedVal: 'b'};
// can also use switch ... case ...
if (data.selectedVal === 'a') {
data.optionASelected = true;
} else if (data.selectedVal === 'b') {
data.optionBSelected = true;
}
// assuming you have a template function to handle this data
templateFunc(data);
In your template file:
<!-- template.html -->
<select id="select-wo-helper" >
<option value="a" {{#if optionASelected}} selected {{/if}}>A</option>
<option value="b" {{#if optionBSelected}} selected {{/if}}>B</option>
</select>
Again this may NOT be the best solution of all, but it probably is a very quick work around when you are dealing very few options and wanted a quick fix.
Today I was also facing the same problem I'm creating a Content Management System and to fetch the status of the post I stuck and in searching for a solution, I landed on this page I found a few answers relevant Because I'm using server-side data and when I used document.createElement it is throwing error document is not defined.
The Regex solution worked for me but I want an easy to understand one whether it is verbose so I came with this solution.
Handlebars.registerHelper('getValue', function(value, options) {
if(options.fn(this).indexOf(value) >= 1){
return `selected='selected'`;
}
});
in the template use the code in this way
<select name="post-status" id="post-status">
<option {{#getValue posts.postStatus}} value="Draft" {{/getValue}} >Draft</option>
<option {{#getValue posts.postStatus}} value="private" {{/getValue}} >private</option>
<option {{#getValue posts.postStatus}} value="publish" {{/getValue}} >publish</option>
</select>
If I'm wrong somewhere Please correct me.
Data source
selectedValue: "8",
option:[
{id_sub_proyectop: "8", clave: "021", name: "Cliclismo"},
{id_sub_proyectop: "9", clave: "022", name: "Atletismo"},
],
helper
Handlebars.registerHelper('selected', function(value, prop) {
if (value === undefined){ return '';};
return value === this[prop] ? 'selected="selected"' : '';
});
Template
<div class="medium-6 cell">
<label>Sub Proyecto / Proceso:
<select name="id_sub_proyectop" required>
{{#each option}}
<option value="{{id_sub_proyectop}}" {{{selected ../selectedValue 'id_sub_proyectop'}}}>{{clave}} - {{name}}</option>
{{/each}}
</select>
</label>
</div>
It should be mentioned that if you do not care about repeats... you can just use vanilla handlebars and place the selected option first, such as:
<select name="ingredient">
<option value="{{ingredient.id}}" selected>{{ingredient.name}}</option>
{{#each ingredients}}
<option value="{{this.id}}">{{this.name}}</option>
{{/each}}
</select>
#lazd's answer does not work for <option> elements within an <optgroup>.
selectedIndex is numbered monotonically for all <option>s, but select.children holds the <optgroup>s, and select.children[n].children holds the <option>s within <optgroup> n (with numbering restarting within each <optgroup>, of course).
This alternative version will work for <option> elements within <optgroup>s:
Handlebars.registerHelper('select-optgrp', function(value, options) {
var select = document.createElement('select'); // create a select element
select.innerHTML = options.fn(this); // populate it with the option HTML
select.value = value; // set the value
var g = 0, i = select.selectedIndex; // calculate which index of which optgroup
while (i >= select.children[g].children.length) { i -= select.children[g].children.length; g++; }
if (select.children[g].children[i]) { // if selected node exists add 'selected' attribute
select.children[g].children[i].setAttribute('selected', true);
}
return select.innerHTML;
});
Another one solution using express-handlebars and dynamic options is this.
Helper function (From all options takes the one we want and change it to selected).
select: function(selected, options) {
return options.fn(this)
.replace( new RegExp(' value=\"' + selected + '\"'), '$& selected="selected"')
.replace( new RegExp('>' + selected + '</option>'), ' selected="selected"$&');
}
handlebars file (I just use #each inside select to receive me data and worked like a charm).
<select name="justAname">
{{#select content.campusId}}
{{#each campus}}
<option value="{{id}}">{{name}}</option>
{{/each}}
{{/select}}
</select>
Handlebars.registerHelper('select', function( value, options ){
return options.fn(this)
.replace( new RegExp(' value=\"' + value + '\"'), '$& selected="selected"')
.replace( new RegExp('>' + value + '</option>'), ' selected="selected"$&');
});
user.country from db session
country stored in country.json file
<select id="country" name="country" class="form-control">
<option value="" selected="selected">(please select a country)</option>
{{#select user.country}}
{{#each countries as |value key| }}
<option value="{{ value.code }}">{{ value.name }}</option>
{{/each}}
{{/select}}
</select>
I know this does not answer the question directly, but in this situation, I passed the unselected html options to the template, and after it is rendered, I use jquery to
mark as selected the value that the json object indicates
for arrays
function select(selected, options) {
return options.fn(this).replace( new RegExp(' value=\"' + selected + '\"'), '$& selected="selected"').replace( new RegExp('>' + selected + '</option>'), ' selected="selected"$&');
},
I was wondering what am I doing wrong here?
I have the following HTML:
<select name="somename" id="DropDownList1">
<option value=""></option>
<option value="1" valp="7700000000000000">Item 1</option>
<option value="2" valp="7C08000000000000">Item 2</option>
<option value="3" valp="5800000000000000">Item 3</option>
</select>
And the following JS/JQuery code that is called when the page loads:
$('#DropDownList1').change(function () {
onChangeDropDownList1(this);
});
function onChangeDropDownList1(obj) {
var vP = $(obj).attr('valp');
alert("valp=" + vP);
};
As the result I get "valp=undefined"
this in context of the .change() refers to the <select> rather than the <option>, so you're not getting the node with the valp attribute.
$('#DropDownList1').change(function () {
onChangeDropDownList1(this);
});
function onChangeDropDownList1(obj) {
// Get the selected option
var vP = $(obj).find(':selected').attr('valp');
alert("valp=" + vP);
};
Here is a demonstration.
The change function is providing you the select which was updated not the option. You need to query the :selected value out of it. Once you have the selected option you can query for the valp attribute
function onChangeDropDownList1(obj) {
var vP = $(obj).find('option:selected').attr('valp');
alert("valp=" + vP);
};
Fiddle: http://jsfiddle.net/Jpfs3/
Pass the option, not the select:
onChangeDropDownList1($(this).children(':selected'));
or, grab the option from the passed select:
var vP = $($(obj).children(':selected')).attr('valp');
Just put the JS code before the end of the body