Inline edit html table with ajax php checkbox & select - javascript

Final Edit: I abandoned trying to get checkboxes to work with this method. Instead, I'm just using a combo box with a 'Yes' and 'No'. Combos are working perfectly, thanks to some fantastic help from SE users :) It actually turns out to be better, IMO. Checkboxes with inline editing, the way I've implemented it could lead to accidentally checked or unchecked boxes. A combo is an extra 2 clicks but it's worth it to eliminate accidents. It also looks great because I'm just swapping a little red 'x' or green 'check' to indicate on and off. It looks really nice. Thanks again to everyone for your help!
I'm using the method from 9lessons.info to create a table with inline-editable rows. So far, it's working but not very well when it comes to selects and checkboxes. With selects, it does update the value, but when it hides the input (when clicking outside the tr) the value of the select shows (the fk id field), rather than the text in between opening and closing of the selected option tag (the name field). I can see in the jQuery where it shows the value, but how do I tell it to use the text from the option instead of the value?
the jQuery:
$(document).ready(function(){
$(".edit_tr").click(function(){
var ID=$(this).attr('id');
// hide
$("#name_"+ID).hide();
$("#position_"+ID).hide();
$("#parent_nav_"+ID).hide();
$("#is_disp_"+ID).hide();
// show
$("#name_input_"+ID).show();
$("#position_input_"+ID).show();
$("#parent_nav_input_"+ID).show();
$("#is_disp_input_"+ID).show();
}).change(function(){
var ID=$(this).attr('id');
var name=$("#name_input_"+ID).val();
var position=$("#position_input_"+ID).val();
var parent_nav = $("#parent_nav_input_"+ID).val();
var is_disp = $("#is_disp_"+ID).prop("checked") ? 1 : 0;
// data string
var dataString = 'id='+ ID +'&name='+name+'&position='+position+'&parent_nav='+parent_nav+'&is_disp='+is_disp;
if(name.length > 0 && position.length > 0 && parent_nav.length > 0) {
var parent_nav_txt = $("#parent_nav_input_"+ID+" option:selected").text();
$.ajax({
type: "POST",
url: "admin_nav_edit.php",
data: dataString,
cache: false,
success: function(html) {
$("#name_"+ID).html(name);
$("#position_"+ID).html(position);
$("#parent_nav_"+ID).html(parent_nav_txt);
$("#is_disp_"+ID).html(is_disp);
}
});
} else {
alert('Enter something.');
}
});
//edit input box click action
$(".editbox").mouseup(function(){
return false
});
//outsire click action
$(document).mouseup(function() {
$(".editbox").hide();
$(".text").show();
});
});
I know the 'is_disp' variables in script are not retrieving the right thing, but everything else works so I don't think I need to post the rest of my code, but I will if necessary.
So, what should I put to get it to recognize the checkbox is unchecked, and make sure a 0 gets sent to the db, or a 1 if checked? That's how I've been doing it
With the select, I'm not sure what do to, or how to target the value in between the select tags to show instead of the value="" value, while making sure the value="" value gets stored in the db.
Thanks very much for any help!

to get a select boxes option's text use the :selected selector along with .text()
var text = $("#selectID option:selected").text();
var value = $("#selectID option:selected").val();
for checkbox check the return of .prop("checked")
var check = $("#checkboxID").prop("checked") ? 1: 0;
EDIT:
var parent_nav_text = $("#parent_nav_input_"+ID+" option:selected").text();
Then in your ajax function
$.ajax({
type: "POST",
url: "admin_nav_edit.php",
data: dataString,
cache: false,
success: function(html) {
$("#name_"+ID).html(name);
$("#position_"+ID).html(position);
$("#parent_nav_"+ID).html(parent_nav_text);
$("#is_disp_"+ID).html(is_disp);
}
});

A call to .val() on a checkbox will always return the value it is set with in the DOM. You should instead do this:
var is_disp = $("#is_disp_input_"+ID).is(':checked');
the .is() jQuery function returns true if the element has the CSS selector, in this case :checked.
Also, on the server, you should check if the checkbox variable is true or false using if(!empty($_POST['myvar'])) {} instead of if(isset($_POST['myvar'])) {} because isset() will return true even if myvar is zero or false!

Related

Persisting checked state using localstorage

I have taken the following snippet from a previously asked question on how to store the checked/unchecked status of all checkboxes on a page in localstorage:
$(function(){
var test = localStorage.input === 'true'? true: false;
$('[type="checkbox"]').prop('checked', test || false);
});
$('[type="checkbox"]').on('change', function() {
localStorage.input = $(this).is(':checked');
console.log($(this).is(':checked'));
});
When I select one of the checkboxes and then refresh the page, once it reloads every single checkbox is checked.
How would I make this store each individual checked state?
Note I may have between 0 - 50 check boxes available depending on how many outstanding records there are in my gridview so I don't have fixed input id's to use only a record id associated to each row.
If you want to rely on a localStorage solution, you may do something like this:
$(function(){
$('[type="checkbox"]').each(function () {
var $this = $(this),
name = $this.attr('name');
$this.prop('checked', localStorage[name] === 'true');
});
});
$('[type="checkbox"]').on('change', function() {
var $this = $(this),
name = $this.attr('name');
localStorage[name] = $this.is(':checked');
});
http://jsfiddle.net/mct7xgq2/
The first part is executed on page load and sets the checked state depending on the localStorage[name] value, where name is the input's name attribute.
The second part executes when any checkbox is being changed: it takes the input's name, as before, but instead of reading the value, it writes it.
IF the page would not load, it would be better to just store the values in JS object rather than using localStorage .
Just create a JS object and keep pushing values inside it and store
Client Side Solution if the page does not reload
$(function(){
var checkedItems ={};
$('[type="checkbox"]').on('change', function() {
//Store the ID value also in the localstorage
if($(this).is(':checked')){
var id = $(this).attr('id'); //Get the id if this is checked
checkedItems['id_'+id] = id;
}
});
});
If Page reloads, then your best bet is to use server side concepts like Session.
Send an AJAX request each time a particular checkbox is checked and store it in a session.
SERVER SIDE SOLUTION
$(function(){
$('[type="checkbox"]').on('change', function() {
//Store the ID value also in the localstorage
if($(this).is(':checked')){
var id = $(this).attr('id'); //Get the id if this is checked
$.ajax({
type: 'POST',
url: your server side url path, //store it in a session
data: {'id':id},
dataType: 'html',
success: function(result){
//so some functionality
}
});
}
});
});
Check out the FIDDLE LINK
This is a solution for d3.js with a ternary operator use. It compares the id of this checkbox with the values stored under key=id in localStorage.
If the value is "true" then 'this.checked' is set to 'true', else to 'null' ( null indicates: no 'checked' property)
var box = d3.selectAll(".box").each(function(){
var id = this.id;
var storageValue = localStorage.getItem(id);
this.checked = storageValue === "true" ? true : null;
});
Previously I have setItem in localStorage. The checkbox are created dynamically appended to rows in a table
rows.append('input')
.attr('type','checkbox')
which in turn is based on the data from a cvs. With the following ids for the checkboxes:
.attr("id", function(d,i) { return 'box'+' '+i; })
And the 'change' of the checkbox state:
d3.selectAll(".box").on("change", function() {
var id = this.id;
if ( this.checked ){
localStorage.setItem(id, this.checked);
}
else {
localStorage.removeItem(id);
}
});
I have thousands of rows, each with a checkbox. I did not see a major issue on the timeline inspection. So I guess that this is a good solution. I am not a d3.js expert.

Set Chosen value from option text

I have a form which uses the Chosen dropdown. If the option the user wants is not available then they can show a modal with a form to add a new option. After the new option is submitted then the modal closes and the data stays in the fields and the chosen option is selected.
How do I set the chosen option selected by the text with jquery/JS. I wont know the value as its an id that is added in the database
$('#save_town').click(function(e){
e.preventDefault();
var town_name = $('#new_town').val();
var region_id = $('#new_region').val();
$.ajax({
type: 'POST',
data: {town_name: town_name, region_id: region_id},
url: '{/literal}{$base_url}{literal}settings/towns/do-add',
success: function(result){
$('.modal').modal('hide');
location.reload();
},
error: function(){
}
});
});
I´m not sure I understand your question correctly, but maybe thats an solution:
$('option').each(function(){
if($(this).html() == "goodby"){
$(this).attr('selected','selected');
}
});
with this, you can select an option by its text.
example: http://jsfiddle.net/TQnTy/

Converting Span to Input

I am developing web app, I have such a requirement that whenever user click on text inside span i need convert it into input field and on blur i need to convert it back to span again. So i am using following script in one of my jsp page.
Java Script:
<script type="text/javascript">
function covertSpan(id){
$('#'+id).click(function() {
var input = $("<input>", { val: $(this).text(),
type: "text" });
$(this).replaceWith(input);
input.select();
});
$('input').live('blur', function () {
var span=$("<span>", {text:$(this).val()});
$(this).replaceWith(span);
});
}
JSP Code:
<span id="loadNumId" onmouseover="javascript:covertSpan(this.id);">5566</span>
Now my problem is, everything works fine only for the first time. I mean whenever i click on the text inside span for the first time it converts into input field and again onblur it coverts back from input field to normal text. But if try once again to do so it won't work. Whats wrong with above script?
Would be good to change your dom structure to something like this (note that the span and the input are side by side and within a shared parent .inputSwitch
<div class="inputSwitch">
First Name: <span>John</span><input />
</div>
<div class="inputSwitch">
Last Name: <span>Doe</span><input />
</div>
Then we can do our JS like this, it will support selecting all on focus and tabbing to get to the next/previous span/input: http://jsfiddle.net/x33gz6z9/
var $inputSwitches = $(".inputSwitch"),
$inputs = $inputSwitches.find("input"),
$spans = $inputSwitches.find("span");
$spans.on("click", function() {
var $this = $(this);
$this.hide().siblings("input").show().focus().select();
}).each( function() {
var $this = $(this);
$this.text($this.siblings("input").val());
});
$inputs.on("blur", function() {
var $this = $(this);
$this.hide().siblings("span").text($this.val()).show();
}).on('keydown', function(e) {
if (e.which == 9) {
e.preventDefault();
if (e.shiftKey) {
$(this).blur().parent().prevAll($inputSwitches).first().find($spans).click();
} else {
$(this).blur().parent().nextAll($inputSwitches).first().find($spans).click();
}
}
}).hide();
I understand you think that element replacement is a nice thing, however, I would use a prompt to get the text. Why? It is a lot easier and actually a bit prettier for the user as well. If you are curious on how to do it, I show you.
html:
<span class='editable'>foobar</span>
js:
$(function()
{
$('span.editable').click(function()
{
var span = $(this);
var text = span.text();
var new_text = prompt("Change value", text);
if (new_text != null)
span.text(new_text);
});
});
http://jsfiddle.net/qJxhV/1/
First, you need to change your click handler to use live() as well. You should take note, though, that live() has been deprecated for quite a while now. You should be using on() in both cases instead.
Secondly, when you replace the input with the span, you don't give the element an id. Therefore, the element no longer matches the selector for your click handler.
Personally, I would take a different (and simpler) approach completely. I would have both the span and in the input in my markup side by side. One would be hidden while the other is shown. This would give you less chance to make mistakes when trying to recreate DOM elements and improve performance since you won't constantly be adding/removing elements from the DOM.
A more generic version of smerny's excellent answer with id's can be made by slightly altering two lines:
$input.attr("ID", "loadNum"); becomes $input.attr("ID", $(this).attr("ID")); -- this way, it simply takes the current id, and keeps it, whatever it is.
Similarly,
$span.attr("ID", "loadNum"); becomes $span.attr("ID", $(this).attr("ID"));
This simply allows the functions to be applied to any div. With two similar lines added, both id and class work fine. See example.
I have done little change in code, By using this input type cant be blank, it will back to its real value.
var switchToInput = function () {
var $input = $("<input>", {
val: $(this).text(),
type: "text",
rel : jQuery(this).text(),
});
$input.addClass("loadNum");
$(this).replaceWith($input);
$input.on("blur", switchToSpan);
$input.select();
};
var switchToSpan = function () {
if(jQuery(this).val()){
var $text = jQuery(this).val();
} else {
var $text = jQuery(this).attr('rel');
}
var $span = $("<span>", {
text: $text,
});
$span.addClass("loadNum");
$(this).replaceWith($span);
$span.on("click", switchToInput);
}
$(".loadNum").on("click", switchToInput);
jsFiddle:- https://jsfiddle.net/svsp3wqL/

How to alert once in a JavaScript loop

code : In the below code shown, the alert message keeps on looping till the end of the statement.I need a alert statement to alert only once.How to achieve this?
Here it is checking the output of a checkbox if its not selected it shows undefined
for(j=1;j<=numOflimit;j++)
{
var select = $("input[name=select+j]:checked").val();
//alert (select);
//$check='undefined';
if(select==undefined)
{
alert ("Please select atleast one product");
}
else
{
var postData = $("form").serialize();//"product_name="+product_name+"&barcode="+barcode+"&Quantity"+Quantity;
$.ajax
({
type: 'POST',
url: 'http://localhost/example/index.php/castoutput',
data: postData,
success: function(html) {
// alert(html);
$('#cast2').html(html);
}
});
}
}
You could make a variable which is either true or false, if the alert has been triggered once put it on false & check with an if, if its true or false.
if (showAlert==true)
{
alert ("Please select atleast one product");
showAlert = false;
}
You're using a string instead of a concatenation here:
$("input[name=select+j]:checked").val();
You need to place j outside of the quotes:
$("input[name=select"+j+"]:checked").val();
Otherwise it is always undefined.
Just curious, by the way, why do you need to loop here anyway?
There is absolutely no reason what-so-ever to loop over input elements to determine if any of them are checked. Since you're already using the :checked selector, simply check the length of the matched set of elements - it's very simple:
var $checked = $("input[type='checkbox']:checked");
// If none of the checkboxes are checked, alert to the user
if ( !$checked.length ) {
alert("Please select atleast one product");
} else {
// do ajax post stuff here.
}
try this
if(typeof(select)=='undefined')
and if you will need to alert once - use yours j counter
if (j==1) {alert('')}
As far as I can tell, you don't want to do the else statement either, so there's no use of letting the for loop run. Simply use:
if(select==undefined)
{
alert ("Please select atleast one product");
j = numOflimit+1;
}
did you try just having it exit the for loop to another function that throws an error if it equals undefined since it looks like your just trying to submit the form. So just make it exit on undefined to a function that throws an alert saying whatever you like.

Using JavaScript or jQuery, how do I check if select box matches original value?

Just wondering if there is any way to check if the value of a select box drop-down matches the original value at the time of page load (when the value was set using selected = "yes") ?
I guess I could use PHP to create the original values as JavaScript variables and check against them, but there are a few select boxes and I'm trying to keep the code as concise as possible!
That's not too hard at all. This will keep track of the value for each select on the page:
$(document).ready(function() {
$("select").each(function() {
var originalValue = $(this).val();
$(this).change(function() {
if ($(this).val() != originalValue)
$(this).addClass('value-has-changed-since-page-loaded');
else
$(this).removeClass('value-has-changed-since-page-loaded');
});
});
});
This will apply a new class value-has-changed-since-page-loaded (which presumably you'd rename to something more relevant) to any select box whose value is different than it was when the page loaded.
You can exploit that class whenever it is you're interested in seeing that the value has changed.
$(document).ready(function() {
var initialSelectValue = $('#yourselect').val();
// call this function when you want to check the value
// returns true if value match, false otherwise
function checkSelectValue() {
return $('#yourselect').val() === initialSelectValue;
}
});
PS. You should use selected="selected" not selected="yes".
On page load, create an array with the initial value of each select box indexed by name:
var select_values = [];
$(document).ready(function() {
$("select").each(function() {
select_values[$(this).attr('name')] = $(this).val();
});
});
later when you need to check if a value has changed:
function has_select_changed(name) {
return $("select[name="+name+"]").val() != select_values[name];
}
First, a snippet:
$('select').each(
function(){
if( this.options[ this.selectedIndex ].getAttribute('selected') === null ){
alert( this.name +' has changed!')
}
});
Now the explanation:
Assuming selectElement is a reference to a <select /> elementYou can check which option is selected using
selectElement.selectedIndex
To get the <option /> element which is currently selected, use
selectElement.options[ selectElement.selectedIndex ]
Now when you know which option element is selected you can find out if this element has the selected='selected' attribute (as in the source code, it doesn't change - this is not the same as .selected propery of a DOM node, which is true for the currently selected option element and changes when the selection is changed)

Categories

Resources