Radio button in content editable div to mysql with ajax - javascript

I'm using an editablecontent div with some radio button inside it, then i send the result to mysql with an ajax request.
<div class="big_wrapper" style="box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); padding: 10px;" contenteditable>
-----------------------TEXT HERE-------------------------
-----------------------TEXT HERE-------------------------
-----------------------TEXT HERE-------------------------
<input type="radio" name="r1" value="choice 1" /> Choice 1
<br><br>
-----------------------TEXT HERE-------------------------
<input type="radio" name="r1" value="choice 2" /> Choice 2
<br><br>
-----------------------TEXT HERE-------------------------
<input type="radio" name="r1" value="choice 3" /> Choice 3
<br><br>
-----------------------TEXT HERE-------------------------
</div>
-----------------------TEXT HERE-------------------------
-----------------------TEXT HERE-------------------------
-----------------------TEXT HERE-------------------------
<button class="btn btn-blue btn-effect" type="button" id="mybutt">Envoyer</button>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
$('#mybutt').click(function(){
var myTxt = $('.big_wrapper').html();
$.ajax({
type: 'post',
url: '/sent_data.php',
data: 'q1=' +myTxt+ ''
});
});
</script>
It's correctly sended to mysql, except the choice of one of the three radio button, it doesn't record correctly in mysql => the checked="checked" is not recorded.
Any help will be appreciated.

It seems that the content of the contenteditable element is treated as text, and it seems unlikely you'll be able to get it to act like a form input. If you search here on SO you will find plenty of other questions asking how to allow HTML inside a contenteditable element, here's an example: HTML Elements inside Contenteditable? The answers show that indeed the content is plain text, and you will need to parse it and convert HTML entites to actually change it into HTML. So unless you do that, your form inputs aren't going to act like actual form inputs, and the selected value definitely won't be available. Maybe that's an option for you, but it does not seem like a good solution to me.
It isn't clear why you want the radio buttons inside the contenteditable element, but a simple and obvious alternative would be to split them up. You can have either one or multiple contenteditables, and your radio buttons will be real radio buttons, so you can easily find the selected option. You simply collect up the results to send on button click.
Working example below. The POST data sent_data.php will receive will look like this:
_POST: Array
(
[texts] => Array
(
[0] => text a
[1] => more text b
[2] => last text c
)
[value] => choice 2
)
If you need to combine that into a single text, you can process it on the back end in PHP (or on the front end in JS of course).
$('#mybutt').click(function () {
// We will save all texts in an array
let texts = [];
let $textFields = $('.big_wrapper');
$textFields.each(function (i) {
texts[i] = $(this).html();
});
// Now get the single radio value
let value = $('input[name="r1"]:checked').val();
// POST away, combining results;
/*
$.ajax({
type: 'post',
url: '/sent_data.php',
data: {
'texts': texts,
'value': value
}
});
*/
// For SO show results on console
let data = {
'texts': texts,
'value': value
};
console.dir(data);
});
.big_wrapper {
border: 1px solid black;
}
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div class="big_wrapper" contenteditable></div>
<input type="radio" name="r1" value="choice 1" /> Choice 1
<br><br><div class="big_wrapper" contenteditable></div>
<input type="radio" name="r1" value="choice 2" /> Choice 2
<br><br><div class="big_wrapper" contenteditable></div>
<input type="radio" name="r1" value="choice 3" /> Choice 3
<br><br><button class="btn btn-blue btn-effect" type="button" id="mybutt">Envoyer</button>

Related

How to deselect the checkbox once it's selected in HTML using jquery?

I am having some problems regarding the jquery event handler function. I couldn't understand how can I set it in the correct way.
I will explain my problem, I have three checkboxes: 3D, TRI-Planar, and MPR. And when users check the 3D option the following two checkboxes appear Volume and Sur. Furthermore, when the user clicks the vol checkbox, some options toggle. And when the user unclicks the vol disappear and again if they click them then there will be two options of same. How can I solve it?
Below I have provided a minimal example which I used first without using a class like desire_viewer and method_selection. If you click 3D then vol and sur options toggle and if you click vol options then another options toggle but when u unclick it then it disappears and then click it again then two same options appear. I think there is something wrong with the code.
I expect the output to be like this: If the user clicks 3D options then it should toggle Volume and Surface options and again if the user clicks on the volume checkbox then volume options should toggle vice-verse with the surface. When the user unchecks any checkbox then its process should stop. For example, at first, the user clicked 3D > VOL and then 3D > sur, in this case, the first step should be stopped when the sur checkbox is clicked. I mean like logic 0 and 1. If the user clicks Tri-Planar then it's 1 and its option should toggle and again if the user unchecks it which is 0 then it's processed and should be stopped. So, in the next step user can play with MPR or other checkboxes.
ID_3D_render_selection = "#v1"
ID_tri_planar = "#v2"
ID_mpr_selection = "#v3"
ID_vol_selection = "#r1"
ID_sur_selection = "#r2"
$(ID_3D_render_selection).change(function() {
$('#select_render_method').slideToggle("slow");
$(ID_vol_selection).change(function() {
$('#VOL_OPTIONS').slideToggle("slow");
var vol_arr = []
var vol_arr2 = []
$( "#btn1" ).change(function() {
var vol_myFile = $('#btn1').prop('files');
vol_arr.push(vol_myFile)
});
<!--//////////////////////////////////////-->
$(document).ready(function() {
var vol_opacity = $('<input class=vol_set_opacity id="setScalarOpacityUnitDistance0" type="range" min="0" max="100" step="0.5" value="3">').appendTo('#set_opacity_distance_bm_Color');
var vol_distance = $('<input class=vol_set_distance id="setSampleDistance0" type="range" min="0.1" max="10" step="0.1" value="0.4">').appendTo('#set_opacity_distance_bm_Color');
var vol_blending = $('<select class=vol_blending_mode id=blendMode0 >').appendTo('#set_opacity_distance_bm_Color');
vol_blending.append($("<option>").attr('value',"0").text("Composite"));
var sel = $('<select class=colors_channels >').appendTo('#set_opacity_distance_bm_Color');
sel.append($("<option>").attr('value',"Reds").text("Reds"));
sel.append($("<option>").attr('value',"Blues").text("Blues"));
sel.append($("<option>").attr('value',"Greens").text("Greens"));
$( "#f" ).change(function() {
$('.vol_set_opacity').remove();
$('.vol_set_distance').remove();
$('.vol_blending_mode').remove();
$('.colors_channels').remove();
for(i=0; i<$('#f').val(); i++) {
var vol_opacity = $('<input class=vol_set_opacity id="setScalarOpacityUnitDistance'+ i +'"'+ ' type="range" min="0" max="100" step="0.5" value="3">').appendTo('#set_opacity_distance_bm_Color');
var vol_distance = $('<input class=vol_set_distance id="setSampleDistance'+ i + '"' + 'type="range" min="0.1" max="10" step="0.1" value="0.4">').appendTo('#set_opacity_distance_bm_Color');
var vol_blending = $('<select class=vol_blending_mode id="blendMode'+ i +'"'+ ' >').appendTo('#set_opacity_distance_bm_Color');
vol_blending.append($("<option>").attr('value',"0").text("Composite"));
var sel = $('<select class=colors_channels >').appendTo('#set_opacity_distance_bm_Color');
sel.append($("<option>").attr('value',"Reds").text("Reds"));
sel.append($("<option>").attr('value',"Blues").text("Blues"));
sel.append($("<option>").attr('value',"Greens").text("Greens"));
}
})
});
<!--//////////////////////////////////////-->
$( "#btn2" ).click(function() {
var vol_Picked_color = $(".colors_channels");
for(var i = 0; i < vol_Picked_color.length; i++){
vol_arr2.push($(vol_Picked_color[i]).val() );
}
console.log(vol_arr2)
if (vol_arr.length==vol_arr2.length){
vol_processFile(vol_arr, vol_arr2)
} else {
alert("Please check the number of input vs the number of channels ")
}
});
});
});
var tri_arr =[]
$(ID_tri_planar).click(function() {
$('#TRI_PLANAR_OPTIONS').slideToggle("slow");
});
$( "#btn1" ).change(function() {
var tri_myFile = $('#btn1').prop('files');
tri_arr.push(tri_myFile)
});
$( "#btn2" ).click(function() {
tri_processFile(tri_arr)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="{% static '/js/jquery-3.6.0.min.js' %}"></script>
<div >
<input class="desire_viewer" type="checkbox" name="Viewers" id="v1" value="3D"><label for="v1">3D</label>
<input class="desire_viewer" type="checkbox" name="Viewers" id="v2" value="TRI-Planar"><label for="v2">TRI-Planar</label>
<input class="desire_viewer" type="checkbox" name="Viewers" id="v3" value="MPR"><label for="v3">MPR</label>
</div>
<div id="select_render_method" class="section_header_2" style="display:none;">
<input class="method_selection" type="checkbox" name="Render" id="r1" value="Vol" ><label for="r1">Vol</label>
<input class="method_selection" type="checkbox" name="Render" id="r2" value="Sur" ><label for="r2">Sur</label>
</div>
<div id="divInput" class="section_internal_layout_card_middle_body_title_4" >
<table>
<tbody>
<td>Select the number of inputs:</td>
<td>
<input min=1 max=10 type="number" id="f" value="1" style="width: 43px; height: 25px;">
</td>
</tbody>
</table>
<div>
<input name="inputFile" type="file" multiple id="btn1" style="margin-left: 1px; margin-top: 30px; padding: 0px; border: none; z-index: 1;">
</div>
<div>
<button name="render" id="btn2" style="margin-top: 0px; margin-left:304px; width: 96px; font-size: 14pt; border: none; z-index: 1; margin-bottom: 7px;"> Render </button>
</div>
</div>
<div id="VOL_OPTIONS" class="section_header_5" style="display:none;">
<div id="set_opacity_distance_bm_Color" class="section_internal_layout_card_middle_body_title_5">
<p><b>Scalar Opacity</b>&ensp<b>SampleDistance</b><b>Blending</b><b>Color</b></p>
</div>
</div>
<div id="SUR_OPTIONS" class="section_header_6" style="display:none;">
<div id="set_iso_Color" class="section_internal_layout_card_middle_body_title_55">
<p><b>Scalar Opacity</b><b>Iso value</b><b>Color</b> </p>
</div>
</div>
<div id="TRI_PLANAR_OPTIONS" class="section_header_7" style="display:none;">
<table>
<tbody>
<tr>
<td>XY</td>
<td>
<input class="XY" type="range" min="0" max="119" step="1" value="0"> <!-- sliceI -->
</td>
</tr>
<tr>
<td>XZ</td>
<td>
<input class="XZ" type="range" min="0" max="119" step="1" value="0"> <!-- sliceJ -->
</td>
</tr>
<tr>
<td>YZ</td>
<td>
<input class="YZ" type="range" min="0" max="119" step="1" value="0"> <!-- sliceK -->
</td>
</tr>
<tr>
<td>Color level</td>
<td>
<input class="colorLevel" type="range" min="0" max="255" step="1" value="0">
</td>
</tr>
<tr>
<td>ColorWindow</td>
<td>
<input class="colorWindow" type="range" min="0" max="255" step="1" value="0">
</td>
</tr>
</tbody>
</table>
</div>
<div id="MPR_OPTIONS" class="section_header_8" style="height:412px; display:none;">
<table><tbody><tr> // do some stuff </tr></tbody></table>
</div>
UPDATE:
OP has edited their question significantly and much of my original answer now makes no sense. Here's a new answer for the current code.
Leaving my original answer below for reference.
The main problem in the new code is that your volume toggle actions are not balanced - the untick action does not do the reverse of the tick action.
When you tick the volume checkbox, you add some HTML to the page, display it, and set up some new change handlers;
When you untick that same checkbox, you add the same HTML again, hide it, and add another set of identical change handlers on top of the first set;
So you can see that if you tick to volume checkbox, untick it, and then tick it again, you will see 2x your HTML on the page.
The other major problem is what I described in my original answer below as "problem 2" - you are adding event handlers inside event handlers. In the example tick/untick/tick example of the volume checkbox above, you will end up with 2x handlers for #f, and 2x handlers for #btn1. If, for eg, you click #btn1, that code will now run 2x, simultaneously. This gets very messy very quickly, and will cause all kinds of problems.
Here's updated, working code, with comments.
Note I have simplified the code a lot by removing lots of stuff which is not relevant to the current problem. Your question summaries the key problem:
... and when the user unclicks the vol disappear and again if they click them then there will be two options of same. How can I solve it?
Ticking and unticking the volume checkbox shows 2x duplicate options. That's the problem we're tying to solve. Everything else here is not relevant, and we can remove it. It is much simpler - for you too! - to find and fix the problem when you focus on just the part that is not working. This is what the minimal in MVCE refers to.
// Document ready event handler should never be nested inside other handlers.
$(document).ready(function() {
// Volume-related variables we need to be able to access later
var vol_opacity, vol_distance, vol_blending, sel;
// Click and change events are technically the same for checkboxes, but still be,
// consistent - use change here, not a mix of change and click as your code had.
// https://stackoverflow.com/questions/11205957/jquery-difference-between-change-and-click-event-of-checkbox
$('#v1').change(function() {
$('#select_render_method').slideToggle("slow");
});
$("#v2").change(function() {
$('#TRI_PLANAR_OPTIONS').slideToggle("slow");
});
// Do not nest event handlers inside each other - move this handler outside other
// change handlers
$('#r1').change(function() {
// We are toggling elements on and off here. If you are ADDing the HTML when
// the checkbox is ticked, it means you have to REMOVE that HTML when it is
// unticked. Is it really necessary? Modifying the DOM like this is slow and
// inefficient, what about just toggling visibility, like you do with
// slideToggle() for other options?
// Anyway - assuming you want to add/remove it, let's do it like this:
if ($(this).is(':checked')) {
addVolumeStuff();
} else {
deleteVolumeStuff();
}
// I moved this toggle below the code above - .appendTo is synchronous, so
// wait until the HTML updates are done before displaying them.
$('#VOL_OPTIONS').slideToggle("slow");
});
/**
* Add some HTML when the vol checkbox is ticked
*/
function addVolumeStuff() {
vol_opacity = $('<input class=vol_set_opacity id="setScalarOpacityUnitDistance0" type="range" min="0" max="100" step="0.5" value="3">').appendTo('#set_opacity_distance_bm_Color');
vol_distance = $('<input class=vol_set_distance id="setSampleDistance0" type="range" min="0.1" max="10" step="0.1" value="0.4">').appendTo('#set_opacity_distance_bm_Color');
vol_blending = $('<select class=vol_blending_mode id=blendMode0 >').appendTo('#set_opacity_distance_bm_Color');
vol_blending.append($("<option>").attr('value',"0").text("Composite"));
sel = $('<select class=colors_channels >').appendTo('#set_opacity_distance_bm_Color');
sel.append($("<option>").attr('value',"Reds").text("Reds"));
sel.append($("<option>").attr('value',"Blues").text("Blues"));
sel.append($("<option>").attr('value',"Greens").text("Greens"));
}
/**
* Delete the volume controls when vol checkbox is unticked
*/
function deleteVolumeStuff() {
vol_opacity.remove();
vol_distance.remove();
vol_blending.remove();
sel.remove();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input class="desire_viewer" type="checkbox" name="Viewers" id="v1" value="3D">3D
<input class="desire_viewer" type="checkbox" name="Viewers" id="v2" value="TRI-Planar">TRI-Planar
<input class="desire_viewer" type="checkbox" name="Viewers" id="v3" value="MPR">MPR
</div>
<div id="select_render_method" class="section_header_2" style="display:none;">
<input class="method_selection" type="checkbox" name="Render" id="r1" value="Vol" >Vol
<input class="method_selection" type="checkbox" name="Render" id="r2" value="Sur" >Sur
</div>
<div>
<input min=1 max=10 type="number" id="f" value="1">
<div>
<input name="inputFile" type="file" multiple id="btn1">
</div>
<div>
<button name="render" id="btn2">Render</button>
</div>
</div>
<div id="VOL_OPTIONS" style="display:none;">
<div id="set_opacity_distance_bm_Color">
<p><b>Scalar Opacity</b> <b>SampleDistance</b> <b>Blending</b> <b>Color</b></p>
</div>
</div>
<div id="SUR_OPTIONS" style="display:none;">
<div id="set_iso_Color">
<p><b>Scalar Opacity</b> <b>Iso value</b> <b>Color</b></p>
</div>
</div>
<div id="TRI_PLANAR_OPTIONS" style="display:none;">
<table>
<tbody>
<tr>
<td>XY</td>
<td>
<input class="XY" type="range" min="0" max="119" step="1" value="0">
</td>
</tr>
<tr>
<td>... etc ...</td>
<td> </td>
</tr>
</tbody>
</table>
</div>
Original answer
Problem 1:
var value = $("input[name='Viewers']:checked").val();
The selector will match all 3 of your checkboxes. But what will the .val() of 3 elements look like? Quoting the docs for .val():
Get the current value of the first element in the set of matched elements.
So you're only ever going to get one of your checkbox values, the first checked one. Try it:
$('.desire_viewer').on('click', function() {
console.log($('.desire_viewer:checked').val());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="desire_viewer" type="checkbox" name="Viewers" value="3D">3D
<input class="desire_viewer" type="checkbox" name="Viewers" value="TRI-Planar">TRI-Planar
<input class="desire_viewer" type="checkbox" name="Viewers" value="MPR">MPR
So how do you check if a particular checkbox is checked? As you can imagine this is a pretty common problem and there are a lot of duplicates here, eg:
Getting all selected checkboxes in an array
Get checkboxes (with the same name) as array
Send same name multiple checkbox values via ajax
You need to iterate over each of the inputs, like so:
$('.desire_viewer').on('click', function() {
console.log('These are now checked:');
$('.desire_viewer:checked').each(function(i) {
console.log(i, ':', $(this).val());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input class="desire_viewer" type="checkbox" name="Viewers" value="3D">3D
<input class="desire_viewer" type="checkbox" name="Viewers" value="TRI-Planar">TRI-Planar
<input class="desire_viewer" type="checkbox" name="Viewers" value="MPR">MPR
Note that inside the loop, $(this) represents the current jQuery object in the loop.
So in your case, your code might look something like:
$('.desire_viewer').on('click', function() {
$('.desire_viewer:checked').each(function(i) {
var val = $(this).val();
if (value == "3D") {
// Do stuff ...
} else if (value == "TRI-Planar") {
// Do other stuff ...
} else if (value == "MPR") {
// Do other different stuff ...
}
});
});
Problem 2:
$( "#btn1" ).change(function() {
This adds an event handler to your button. From this point on, any time that button is changed this handler will notice, and that function code will fire.
That's fine and will work. The problem is where it is added - when a checkbox is clicked. If the user decides they made a mistake and UNticks the TRI-Planar checkbox, guess what happens? Another identical event handler will be added to the button. And the best part? They will both fire! The handler function, whatever it is, will run 2x, in parallel. They don't overwrite each other, they all stack up, and they all run.
The (simplest) solution is to add event handlers independent of user interaction or other changes on the page, so they can only be bound once. If the code that runs is somehow dependent on where/when it would be triggered, set that up in the handler. Eg if this button change should only do something if TRI-Planar is checked, have the button event handler check if that is true before doing anything. Eg:
$("#btn1").change(function() {
// Maybe this should only happen if a certain checkbox is checked
$('.desire_viewer:checked').each(function(i) {
var val = $(this).val();
if (value == "TRI-Planar") {
// Do stuff
}
});
});
// Rest of your code - handlers are independent of user interaction and
// will only be bound once.
$('.desire_viewer').on('click', function() {
// ...
Note another option is to add handlers wherever you like, and use .off() to remove them, so you can dynamically add/remove them throughout your code. For simple applications I don't think this extra complexity is necessary.
There are lots of questions here about this too:
Is it correct to put an event inside an event?
jQuery click events firing multiple times
why is jQuery click event firing multiple times
Minor suggestion:
It looks like this is part of a bigger applicaton, and it looks like you're trying to reduce code repetition with variables like ID_desire_viewer = '.desire_viewer' etc. That's a good start but since those represent jQuery selectors, you may as well go just a tiny bit further and cache the actual selector.
Every time you do something like $(ID_desire_viewer) jQuery scans the whole DOM again to find matches. For small applications/pages you probably won't notice the performance hit doing that, but it is good practice to avoid it in case your app grows, and just in terms of read- and maintain-ability, DRY, etc.
To avoid that, save the results of the first search by doing:
let $viewers = $('.desire_viewer');
// Then you can do:
$viewers.on('click', function() { ...
Some references about that:
Does jQuery do any kind of caching of "selectors"?
Store jquery selector in variable
Try this
$('input["type=checkbox"]').attr("checked",'false');
i hope it was useful !

Alpine JS Toggle Input Values

I have a button that I want to toggle the value on a html input element from 0 to 1 and vice versa but I can't figure out how to do it with Alpine JS.
// input will be 0 or 1
<input type="hidden" value="0" name="status" x-ref="status">
// Toggles the status between 1 and 0
<button type="button"
x-data="{ on: false }" :class="{ 'bg-gray-200': !on, 'bg-primary-600': on }"
#click="$refs.status.value = 1"
>Toggle Status</button>
I was able to get the code above to change the input value to 1 but can't figure out how to get it to toggle it back and forth. Any ideas would mean a lot.
Here you go
<div x-data="{ status: false }">
<form>
<input type="hidden" value="0" name="status" x-model.number="status">
<span x-text="status"></span>
<button type="button" x-on:click="status = !status">
Toggle Status
</button>
</form>
</div>
The global status is held at the div element. The status is outputted inside a span using x-text.
The hidden input is bound to the status using x-model and transforming the boolean value to a number using the .number modifier.
Update
For whatever reasons this does not work anymore, I created a new sample here: https://codepen.io/codedge/pen/wvgNqee
It just defines two x-data values, one for the boolean value and one for the integer one.
<div x-data="{ status: false, num: 0 }">
<form>
<input type="hidden" value="0" name="num">
<span x-text="num"></span>
<button type="button" x-on:click="status = !status; num = (status == true ? 1 : 0)">
Toggle Status
</button>
</form>
</div>

Dynamically created form from database and accessing elements with jquery

I have form that is created from database. Form contains radio buttons which are created like this
<label>
<input type="radio" name="rizici_radio<?php echo $riz_id ?>"
value="<?php echo $rizik['riz_vrednost_da']; ?>" >
<?php echo $rizik['riz_vrednost_da']; ?>
</label>
Name attribute contains rizici_radio and id from database. And every row has pair of radio buttons with values 1 or 0.
So my problem is manipulating changing values of that pair of radio buttons. For example when i select radio button with value 1 it should fill span tag with value of changed radio button. And i have another span where sum of values from all span tags should be displayed.
Grey is span where value of selected radio button should be stored
Using loop might create issue as some times loop counter value and DB ID's might differ. So what you need to do set DB ID to both radio button set like below where i am setting rel-id value to DB Ids
<label><input type="radio" class="promena" rel-id = '2' name="rizici_radio2" value="1" >1</label>
<label><input type="radio" class="promena" checked rel-id = '2' name="rizici_radio2" value="0">0</label>
And use below jquery code
$(".promena").on("change",function(){ // bind a function to the change event
if( $(this).is(":checked") ){ // check if the radio is checked
var val = $(this).val(); // retrieve the value
var id = $(this).attr("rel-id");
$("#bodovi"+id).val(val); //setting value to respective hidden field
$("#scores"+id).text(val); // showing selected radio button value in gray area
}
});
Hope this helps you.
with jQuery:
$(radiobutton selector here).click(function(){
$(this).next(".greyValueArea").val($(this).val());
})
This should do the trick. just change selectors.
"Selectors i must create from id's. That is my main problem. I must use something like for loop to add id to either name or id"
#Thug you can also give them some class that they would be having incommon.
You see: If you make a
$('.button').on("click",function(){
console.log($this)
})
It will console log button class item you clicked and it applies to every button class you have
First of all, I think it would be better to request the table data with an ajax request as json data from server if you need to update the server data later.
Anyway, for getting the clicked row you can also use the following script:
$('.selectionForm').on('change', 'input[type="radio"]',
function(event) {
console.log('changed radio', $(this).attr('name'), $(this).val(), $(this).parent().find('span'));
$(this).parent().find('span').text($(this).val());
});
It goes up in the DOM to the parent of the clicked radio button and then with find you're going down again to the span of that row.
It uses event delegation because that's required for dynamically added content from the ajax request. That would be not required for the PHP added content.
Please see the demo below and here at jsfiddle.
Handlebars.registerHelper('isChecked', function(input, options) {
//console.log(input, this);
//console.log(this, this.value, input);
return this.value === input? 'checked': '';
});
var $out = $('#out'),
rowTmpl = $("#row-template").html(),
template = Handlebars.compile(rowTmpl);
$.ajax({
url: 'http://www.mocky.io/v2/556d9fd9e822500114253f39',
jsonp: 'callback',
dataType: "jsonp",
success: function(response) {
console.log(response);
$.each(response, function(index, data) {
//console.log(data);
$out.append(template(data));
});
}
});
$('.selectionForm').on('change', 'input[type="radio"]', function(event) {
console.log('changed radio', $(this).attr('name'), $(this).val(), $(this).parent().find('span'));
$(this).parent().find('span').text($(this).val());
});
//$out.html(JSON.stringify(dataArray));
ul {
list-style-type: none;
}
li {
border-bottom: 1px solid gray;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/3.0.3/handlebars.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h1>form loaded with ajax request:</h1>
<p>table generated with javascript</p>
<form class="selectionForm">
<ul id="out"></ul>
<!--<ul>
<li>
<input type="radio" name="row0" value="0"/>0
<input type="radio" checked="" name="row0" value="1"/>1
<span class="badge">1</span>
</li>
<li>
<input type="radio" name="row1" value="0"/>0
<input type="radio" checked="" name="row1" value="1"/>1
<span class="badge">1</span>
</li>
</ul>-->
</form>
<script id="row-template" type="text/x-handlebars-template">
<li>
<input type="radio" value="0" name="row{{id}}" {{isChecked 0 }}/>0
<input type="radio" value="1" name="row{{id}}" {{isChecked 1 }}/>1
<span class="badge">{{value}}</span>
</li>
</script>
<h1>form generated with server side script</h1>
<form class="selectionForm">
<ul>
<li>
<input type="radio" name="row0" value="0"/>0
<input type="radio" checked="" name="row0" value="1"/>1
<span class="badge">1</span>
</li>
<li>
<input type="radio" name="row1" value="0"/>0
<input type="radio" checked="" name="row1" value="1"/>1
<span class="badge">1</span>
</li>
</ul>
</form>

Dynamically adding and removing div using JQuery?

I'm trying to create a form that allows a user to enter their experience and education
I would like the user to be able to add and remove education or experience.
I am able to do this... sort of. Only the problem is my new divs that I am creating are being appended to the end of the page instead of being appended after the previous div.
These are my scripts:
$(document).ready(function() {
var inputs = 1;
$('#btnAdd').click(function() {
$('.btnDel:disabled').removeAttr('disabled');
var c = $('.clonedInput:first').clone(true);
c.children(':text').attr('name', 'input' + (++inputs));
$('.clonedInput:last').after(c);
});
$('.btnDel').click(function() {
if (confirm('continue delete?')) {
--inputs;
$(this).closest('.clonedInput').remove();
$('.btnDel').attr('disabled', ($('.clonedInput').length < 2));
}
});
});
$(document).ready(function() {
var inputs = 1;
$('#btnAdd2').click(function() {
$('.btnDel2:disabled').removeAttr('disabled');
var c = $('.clonedInput:first').clone(true);
c.children(':text').attr('name', 'input' + (++inputs));
$('.clonedInput:last').after(c);
});
$('.btnDel2').click(function() {
--inputs;
$(this).closest('.clonedInput').remove();
$('.btnDel2').attr('disabled', ($('.clonedInput').length < 2));
});
});
I understand it's bad form to duplicate code like this but I'm not sure how else to else to do it so that clicking the add button doesn't get pressed for the wrong div...
and my html is:
<form id="myForm">
<h2>Education</h2>
<p>Please add all of your education</p>
<div style="margin-bottom: 4px; border: 2px solid; border-style: dashed" class="clonedInput">
Level: <select>
<option value="secondary">Secondary</option>
<option value="someps">Some Post Secondary</option>
<option value="college">College</option>
</select> <br /> <br />
Did you receive a degree, diploma or certificate?<br />
<select>
<option value="certificate">Certificate</option>
<option>Diploma</option>
<option value="degree">Degree</option>
</select> <br />
<input type="button" class="btnDel" value="Remove Education" disabled="disabled" />
</div>
<div>
<input type="button" id="btnAdd2" value="add Education" />
</div>
<h2>Experience</h2>
<p>Please add all of your experience</p>
<div style="margin-bottom: 4px; class="clonedInput">
Position title: <input type="text"><br /> Years at position:
<input type="number"><br />
Responsibilities: <input type="text"><br />
<input type="text"><br />
Type: <select>
<option>Accounting, banking and Finance</option>
<option>Publishing & Journalism</option>
<option>Social Care & guidance work</option>
</select>
<input type="button" class="btnDel2" value="Remove Experience"
disabled="disabled" />
</div>
<div>
<input type="button" id="btnAdd2" value="add Experience" />
</div>
</form>
Any ideas on how I can fix my script so that when I click the add button for education, a new div containing all of the fields for "education" show up below the previous education box and the same for education?
Any help would be appreciated. Thanks!
Firstly, why do you have 2x $(document).ready? Combine your code into one.
The reason why your duplicated div appear at the end of the form is because both your Education and Experience divs have class="clonedInput", hence $('.clonedInput:last').after(c) causes the duplicated div to be placed after the Experience section (which happens to be the last div that matches the .clonedInput selector).
A solution would to be give each of these sets of divs their own unique class name, such as eduInput and expInput respectively.
The corrected code would hence be:
$('#btnAdd').click(function() {
$('.btnDel:disabled').removeAttr('disabled');
var c = $('.eduInput:first').clone(true);
c.children(':text').attr('name', 'input' + (++inputs));
$('.eduInput:last').after(c);
});
for the education div.
To clean up your code, I suggest binding both Add buttons to the same handler, but act upon them differently by checking the target parameter and determining which set (Education or Experience) to duplicate. Such as:
// single handler and click event for both buttons
var clickHandler = function (e) {
// determine which btnAdd was clicked, such as e.getAttribute('id')
}
$('.btnAdd').click(clickHandler);
But seriously you should clean up your code a little.

not getting radio button value in javascript

In my application I am trying to get value of radio button but some how not able to get it.
my html is
<div style="border-bottom: 5px Solid #800080;">
<input type="radio" value="0 " name="routeSelect" checked="checked">Route 1</div>
<br>
<div style="border-bottom: 5px Solid #000080;">
<input type="radio" value="1 " name="routeSelect">Route 2</div>
<br>
<input type="button" onclick="alert(getRadioValue());" value="Which?" />
my js is
function getRadioValue() {
var group = document.getElementsByName("routeSelect");
for (var i = 0; i < group.length; i++) {
if (group[i].checked) {
return group[i].value;
}
}
return '';
}
Here Is link : http://jsfiddle.net/aX89G/
can any one tell me what is wrong I am doing
Your code is fine but the getRadioValue function isn't found, it's currently wrapped in a function which is called on load, you must choose No wrap - in <head> in the menu at the left of jsfiddle's window.
This is equivalent to putting the code in a script element in the head of your page.
Demonstration
Alternatively, you could separate your javascript from your HTML this way :
<input id=butt type="button" value="Which?" />
<script>
document.getElementById('butt').onclick=function(){
alert(getRadioValue());
});
</script>
This is usually considered cleaner and easier to maintain.

Categories

Resources