Editing HTML table row data - javascript

Hello Folks..,
I am getting error while updating text field values. When I update one text field, the remaining are all updated automatically with same value.
Here is the link contains my source code:
http://jsfiddle.net/jFycy/284/
My requirement is to update that particular field only.
$(function () {
$(".inner, .inner2").dblclick(function (e) {
e.stopPropagation();
var currentEle = $(this);
var value = $(this).html();
updateVal(currentEle, value);
});
});
function updateVal(currentEle, value) {
$(currentEle).html('<input class="thVal" type="text" value="' + value + '" />');
$(".thVal").focus();
$(".thVal").keyup(function (event) {
if (event.keyCode == 13) {
$(currentEle).html($(".thVal").val().trim());
}
});
$(document).click(function () {
$(currentEle).html($(".thVal").val().trim());
});
}

You can do something like this
$(function() {
$(".inner, .inner2").dblclick(function(e) {
// check text input element contains inside
if (!$('.thVal', this).length)
// if not then update with the input element
$(this).html(function(i, v) {
return '<input class="thVal" type="text" value="' + v + '" />'
});
}).on({
// bind keyup event
'keyup': function(event) {
// on enter key update the content
if (event.keyCode == 13) {
$(this).parent().html($(this).val().trim());
}
},
'blur': function() {
// if focus out the element update the content with iput value
$(this).parent().html($(this).val().trim());
}
}, '.thVal');
});
.inner {
background: red;
}
.inner2 {
background: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="inner">1</div>
<div class="inner2">1</div>
<div class="inner">1</div>
Or much more simpler method with a contenteditable attribute.
.inner {
background: red;
}
.inner2 {
background: grey;
}
<div contenteditable class="inner">1</div>
<div contenteditable class="inner2">1</div>
<div contenteditable class="inner">1</div>

Thing is, you using myltiple inputs and attaching event to every one of it.
Instead, I suggest you to create one input and use exactly this particular input.
function updateVal(currentEle, value) {
var $thval = $('<input class="thVal" type="text" value="' + value + '" />');
$(currentEle).empty().append($thval);
$thval.focus().keyup(function(event) {
if (event.keyCode == 13) {
$(this).blur();
}
}).blur(function(){
$(currentEle).html($(".thVal").val().trim());
$thval.remove();
});
}
http://jsfiddle.net/jFycy/290/

When multiple html element like (OL li) it duplicate value in other controls too. For this I have made this changes, and its working.
$(".updatefield").dblclick(function (e) {
**var len = $('.thVal').length;
if (len > 0) {
$(".thval").remove();
return;**
}
e.stopPropagation(); //<-------stop the bubbling of the event here
var currentEle = $(this);
var value = $(this).html();
updateVal(currentEle, value);
});
function updateVal(currentEle, value) {
var wid = currentEle.width() + 30;
var hei = currentEle.height()+ 10;
//$(currentEle).html('<input class="thVal" type="text" value="' + value + '" />');
$(currentEle).html('<textarea class="thVal">' + value + '</textarea>');
$(".thVal").css("width", wid);
$(".thVal").css("height", hei);
$(".thVal").css("background", "lightyellow");
$(".thVal").focus();
$(".thVal").keyup(function (event) {
if (event.keyCode == 13) {
if ($(".thVal").val() == "")
$(".thVal").val("EMPTY");
$(currentEle).html($(".thVal").val().trim());
}
});
$(document).click(function () { // you can use $('html')
**var e = jQuery.Event("keyup");
e.which = 13; // Enter
e.keyCode = 13; // Enter
$('.thVal').trigger(e);**
});

Related

'DOMException: Failed to execute 'querySelectorAll' on 'Element' when using an 'option:selected' selector

I'm running a page which throws an error at the following line:
var label = $select.find('option:selected').html() || $select.find('option:first').html() || "";
For the sake of completeness, here is the full jQuery function (country-select.js):
(function($) {
$.fn.countrySelect = function (callback) {
$(this).each(function(){
var $select = $(this);
var lastID = $select.data('select-id'); // Tear down structure if Select needs to be rebuilt
if (lastID) {
$select.parent().find('span.caret').remove();
$select.parent().find('input').remove();
$select.unwrap();
$('ul#select-options-'+lastID).remove();
}
// If destroying the select, remove the selelct-id and reset it to it's uninitialized state.
if(callback === 'destroy') {
$select.data('select-id', null).removeClass('initialized');
return;
}
var uniqueID = Materialize.guid();
$select.data('select-id', uniqueID);
var wrapper = $('<div class="select-wrapper"></div>');
wrapper.addClass($select.attr('class'));
var options = $('<ul id="select-options-' + uniqueID +'" class="dropdown-content select-dropdown country-select"></ul>'),
selectChildren = $select.children('option, optgroup'),
valuesSelected = [],
optionsHover = false;
var label = $select.find('option:selected').html() || $select.find('option:first').html() || "";
// Function that renders and appends the option taking into
// account type and possible image icon.
var appendOptionWithIcon = function(select, option, type) {
// Add disabled attr if disabled
var disabledClass = (option.is(':disabled')) ? 'disabled ' : '';
var optgroupClass = (type === 'optgroup-option') ? 'optgroup-option ' : '';
var classes = option.attr('class');
var data = option.data('phone-code');
var opt = '<li class="' + disabledClass + optgroupClass + '"><span>';
if (option.val() !== '') {
opt += '<b class="flag flag-' + option.val().toLowerCase() + '"></b>';
}
opt += '<span class="option-label">' + option.html() + '</span>';
if (data && data !== '') {
opt += '<small>' + data + '</small>';
}
opt += '</span></li>';
options.append($(opt));
};
/* Create dropdown structure. */
if (selectChildren.length) {
selectChildren.each(function() {
if ($(this).is('option')) {
appendOptionWithIcon($select, $(this));
} else if ($(this).is('optgroup')) {
// Optgroup.
var selectOptions = $(this).children('option');
options.append($('<li class="optgroup"><span>' + $(this).attr('label') + '</span></li>'));
selectOptions.each(function() {
appendOptionWithIcon($select, $(this), 'optgroup-option');
});
}
});
}
options.find('li:not(.optgroup)').each(function (i) {
$(this).click(function (e) {
// Check if option element is disabled
if (!$(this).hasClass('disabled') && !$(this).hasClass('optgroup')) {
var selected = true;
options.find('li').removeClass('active');
$(this).toggleClass('active');
$newSelect.val($(this).find('.option-label').text());
activateOption(options, $(this));
$select.find('option').eq(i).prop('selected', selected);
// Trigger onchange() event
$select.trigger('change');
if (typeof callback !== 'undefined') callback();
}
e.stopPropagation();
});
});
// Wrap Elements
$select.wrap(wrapper);
// Add Select Display Element
var dropdownIcon = $('<span class="caret">▼</span>');
if ($select.is(':disabled'))
dropdownIcon.addClass('disabled');
// escape double quotes
var sanitizedLabelHtml = label.replace(/"/g, '"');
var $newSelect = $('<input type="text" class="select-dropdown" readonly="true" ' + (($select.is(':disabled')) ? 'disabled' : '') + ' data-activates="select-options-' + uniqueID +'" value="'+ sanitizedLabelHtml +'"/>');
$select.before($newSelect);
$newSelect.before(dropdownIcon);
$newSelect.after(options);
// Check if section element is disabled
if (!$select.is(':disabled')) {
$newSelect.data('constrainwidth', false)
$newSelect.dropdown({'hover': false, 'closeOnClick': false});
}
// Copy tabindex
if ($select.attr('tabindex')) {
$($newSelect[0]).attr('tabindex', $select.attr('tabindex'));
}
$select.addClass('initialized');
$newSelect.on({
'focus': function (){
if ($('ul.select-dropdown').not(options[0]).is(':visible')) {
$('input.select-dropdown').trigger('close');
}
if (!options.is(':visible')) {
$(this).trigger('open', ['focus']);
var label = $(this).val();
var selectedOption = options.find('li').filter(function() {
return $(this).find('.option-label').text().toLowerCase() === label.toLowerCase();
})[0];
activateOption(options, selectedOption);
}
},
'click': function (e){
e.stopPropagation();
}
});
$newSelect.on('blur', function() {
$(this).trigger('close');
options.find('li.selected').removeClass('selected');
});
options.hover(function() {
optionsHover = true;
}, function () {
optionsHover = false;
});
// Make option as selected and scroll to selected position
var activateOption = function(collection, newOption) {
if (newOption) {
collection.find('li.selected').removeClass('selected');
var option = $(newOption);
option.addClass('selected');
options.scrollTo(option);
}
};
// Allow user to search by typing
// this array is cleared after 1 second
var filterQuery = [],
onKeyDown = function(e){
// TAB - switch to another input
if(e.which == 9){
$newSelect.trigger('close');
return;
}
// ARROW DOWN WHEN SELECT IS CLOSED - open select options
if(e.which == 40 && !options.is(':visible')){
$newSelect.trigger('open');
return;
}
// ENTER WHEN SELECT IS CLOSED - submit form
if(e.which == 13 && !options.is(':visible')){
return;
}
e.preventDefault();
// CASE WHEN USER TYPE LETTERS
var letter = String.fromCharCode(e.which).toLowerCase(),
nonLetters = [9,13,27,38,40];
if (letter && (nonLetters.indexOf(e.which) === -1)) {
filterQuery.push(letter);
var string = filterQuery.join(''),
newOption = options.find('li').filter(function() {
return $(this).text().toLowerCase().indexOf(string) === 0;
})[0];
if (newOption) {
activateOption(options, newOption);
}
}
// ENTER - select option and close when select options are opened
if (e.which == 13) {
var activeOption = options.find('li.selected:not(.disabled)')[0];
if(activeOption){
$(activeOption).trigger('click');
$newSelect.trigger('close');
}
}
// ARROW DOWN - move to next not disabled option
if (e.which == 40) {
if (options.find('li.selected').length) {
newOption = options.find('li.selected').next('li:not(.disabled)')[0];
} else {
newOption = options.find('li:not(.disabled)')[0];
}
activateOption(options, newOption);
}
// ESC - close options
if (e.which == 27) {
$newSelect.trigger('close');
}
// ARROW UP - move to previous not disabled option
if (e.which == 38) {
newOption = options.find('li.selected').prev('li:not(.disabled)')[0];
if(newOption)
activateOption(options, newOption);
}
// Automaticaly clean filter query so user can search again by starting letters
setTimeout(function(){ filterQuery = []; }, 1000);
};
$newSelect.on('keydown', onKeyDown);
});
function toggleEntryFromArray(entriesArray, entryIndex, select) {
var index = entriesArray.indexOf(entryIndex),
notAdded = index === -1;
if (notAdded) {
entriesArray.push(entryIndex);
} else {
entriesArray.splice(index, 1);
}
select.siblings('ul.dropdown-content').find('li').eq(entryIndex).toggleClass('active');
// use notAdded instead of true (to detect if the option is selected or not)
select.find('option').eq(entryIndex).prop('selected', notAdded);
setValueToInput(entriesArray, select);
return notAdded;
}
function setValueToInput(entriesArray, select) {
var value = '';
for (var i = 0, count = entriesArray.length; i < count; i++) {
var text = select.find('option').eq(entriesArray[i]).text();
i === 0 ? value += text : value += ', ' + text;
}
if (value === '') {
value = select.find('option:disabled').eq(0).text();
}
select.siblings('input.select-dropdown').val(value);
}
};
$(function() {
$('.js-country-select').countrySelect();
});
$(document).on('change', '[data-country-select]', function() {
var target = 'select' + $(this).data('country-select');
var val = $(this).val();
var label = 'State';
var options = [
'<option value="" selected="" disabled="">Select State</option>'
];
if (val !== '') {
var country = window.__COUNTRIES[val];
var subdivisions = country.subdivisions;
var keys = Object.keys(subdivisions);
label = country.subdivisionName;
options = [
'<option value="" selected="" disabled="">Select ' + label + '</option>'
];
keys = keys.sort(function(a, b) {
var valA = subdivisions[a].toLowerCase();
var valB = subdivisions[b].toLowerCase();
if (valA < valB) return -1;
if (valA > valB) return 1;
return 0;
});
keys.forEach(function(key) {
options.push('<option value="' + key + '">' + subdivisions[key] + '</option>');
});
$(target).removeAttr('disabled');
} else {
$(target).attr('disabled', 'disabled');
}
$(target).parents('.input-field').find('label').html(label);
$(target).val('').html(options);
$(target).select2();
});
})(jQuery);
Here is the exception that I see in debug mode:
From what I understand from Failed to execute 'querySelectorAll' on 'Element' in ExtJS 5, :selected is not part of the CSS specification.
How should I fix this? Should I use:
var label = $select.find('option').filter(':selected').html() || $select.find('option').filter(':first').html() || "";
?
Converting Phil's comment to an answer, my debugger was set to pause on all exceptions (including caught ones). I had to de-activate the 'stop sign' button shown below to make the debugger work normally again.

javascript datepicker not activating

My problem is that my datepicker does not work when I create my input field through javascript.
I have a button which will generate the fields needed for the input. One of these is a datepicker. I have a function which brings up a small calendar for the user to pick from. It works for input fields that aren't created by the javascript function.
this is the javascript function to create an input field:
<script lang="javascript">
TestNo = 1; // This is input files added by default.
TestMax = 50;
TestMin = 1;
function Test_Addchild() {
if (TestNo <= TestMax) {
var div = document.createElement("div");
div.id = 'divfiles' + TestNo;
//div.style.width = "100px";
//div.style.height = "100px";
//div.style.background = "red";
//div.style.color = "white";
div.innerHTML = '<input size="35" type="text" id="Test' + TestNo + 'D" name="Test' + TestNo + 'D" value="Date ' + TestNo + '" class="form-control selector" autocomplete="off">';
document.getElementById('Tests').appendChild(div);
TestNo++;
$('#<%= NoOfTests.ClientID %>').val(TestNo-1);
return false;
}
else {
alert('Maximum ' + TestMax + ' Files are Allowed.');
return false;
}
}
function Test_Delchild() {
if (TestNo > TestMin) {
cnt = TestNo - 1;
element = document.getElementById('divfiles' + cnt);
element.parentNode.removeChild(element);
TestNo--;
$('#<%= NoOfTests.ClientID %>').val(TestNo-1);
return false;
}
else {
alert('All tests removed');
return false;
}
}
</script>
These are the buttons creating and deleting the input field:
Add more tests<br>
Remove tests<br>
And lastly the datepicker function
<script>
$(function () {
$(".selector").datepicker({
showOtherMonths: true,
selectOtherMonths: true
});
});
</script>
How do I get the datepicker function to work for dynamically created input fields?
Thank you in advance.

how to limit the click event in jquery loop?

I would like to limit click event loop in jquery. I have categories list which will have in the following format and also after 5 click in the loop i have to disable click event.
<div class="col-md-2 col-sm-4 col-xs-6 home_s">
<a class="get_category" id="36" href="javascript:void(0)">
<img class="img-responsive img-center" src="">
<span>xxxxx</span>
</a>
<input type="hidden" value="36" id="categories36" name="categories[]">
</div>
$(document).ready(function() {
$(".get_category").on('click', function() {
var cat_id = $(this).attr('id');
var cat_value = $("#categories" + cat_id).val('');
if ($("#categories" + cat_id).val() == '') {
$("#categories" + cat_id).val(cat_id);
} else {
alert("hi");
$("#categories" + cat_id).val('');
}
})
});
You can use off() to unbind event handler
$(document).ready(function() {
// variable for counting clicks
var i = 1;
var fun = function() {
var cat_id = $(this).attr('id');
var cat_value = $("#categories" + cat_id).val('');
if ($("#categories" + cat_id).val() == '') {
$("#categories" + cat_id).val(cat_id);
} else {
alert("hi");
$("#categories" + cat_id).val('');
}
// checking and increment click count
if (i++ == 5)
// unbinding click handler from element
$(".get_category").off('click', fun);
};
$(".get_category").on('click', fun);
});
Example :
$(document).ready(function() {
var i = 1;
var fun = function() {
alert('clicked'+i);
if (i++ == 5)
$(".get_category").off('click', fun);
};
$(".get_category").on('click', fun);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="get_category">click</button>
If you have multiple .get_category in your html the solution from Pranav C Balan won't work.
$(document).ready(function() {
function clickFunc() {
var click_count = $(this).data('click-count') || 0;
var cat_id = $(this).attr('id');
var cat_value = $("#categories" + cat_id).val('');
if ($("#categories" + cat_id).val() == '') {
$("#categories" + cat_id).val(cat_id);
} else {
alert("hi");
$("#categories" + cat_id).val('');
}
if (++click_count >= 5)
$(this).off('click', clickFunc);
$(this).data('click-count', click_count);
});
$(".get_category").on('click', clickFunc);
});
This way you store the click count on the data-click-count attribute of each .get_category

Using jQuery with meteor giving errors

Omitting the keydown input : function(event) { and } gives me an error along the lines of
"While building the application:
client/client.js:33:11: Unexpected token ("
which is basically the starting. I'm wondering why I need the javascript function right at the start. To not get the error. This is an issue especially because I don't want the click function to run every time the key is pressed. In any case it would be great to either figure out how I can just use jQuery instead of javascript here or change the keydown input.
Template.create_poll.events = {
'keydown input' : function(event) {
$("input").keypress(function() {
var active_element = $(this).parent().attr("id");
var last_child = $('ul li:last').attr("id");
var option_number_index = last_child.lastIndexOf("-");
var option_number = last_child.substring(option_number_index+1);
option_number = option_number/1;
//console.log(option_number);
//console.log(last_child);
if (last_child == active_element) {
console.log(active_element);
option_number += 1;
console.log(option_number);
$('ul').append('<li id="poll-choice-' + option_number + '"><input name="choice" type="text" placeholder="Option ' + option_number + '">');
}
});
$("#poll_create").click(function() {
console.log("Button works");
var choices = new Array();
var counter = 0;
$("ul li input").each(function() {
choices[counter] = $(this).val();
counter++;
});
console.log(choices[1]);
console.log(choices[5]);
});
}
}
Template.create_poll.events expects an eventMap which is:
An event map is an object where the properties specify a set of events to handle, and the values are the handlers for those events. The property can be in one of several forms:
Hence, you need to pass in the 'keydown input' : function (event, templ) { ... } to make it a valid Javascript object.
In this case, you should follow #Cuberto's advice and implement the events using Meteor's event map:
Template.create_poll.events = {
'press input' : function(event) {
var active_element = $(this).parent().attr("id");
var last_child = $('ul li:last').attr("id");
var option_number_index = last_child.lastIndexOf("-");
var option_number = last_child.substring(option_number_index+1);
option_number = option_number/1;
//console.log(option_number);
//console.log(last_child);
if (last_child == active_element) {
console.log(active_element);
option_number += 1;
console.log(option_number);
$('ul').append('<li id="poll-choice-' + option_number + '"><input name="choice" type="text" placeholder="Option ' + option_number + '">');
}
},
'click #poll_create' : function (event) {
console.log("Button works");
var choices = new Array();
var counter = 0;
$("ul li input").each(function() {
choices[counter] = $(this).val();
counter++;
});
console.log(choices[1]);
console.log(choices[5]);
}
}
However, if you want to use certain jQuery specific events, then you can attach them in the rendered function:
Template.create_poll.rendered = function () {
$("input").keypress(function() {
var active_element = $(this).parent().attr("id");
var last_child = $('ul li:last').attr("id");
var option_number_index = last_child.lastIndexOf("-");
var option_number = last_child.substring(option_number_index+1);
option_number = option_number/1;
//console.log(option_number);
//console.log(last_child);
if (last_child == active_element) {
console.log(active_element);
option_number += 1;
console.log(option_number);
$('ul').append('<li id="poll-choice-' + option_number + '"><input name="choice" type="text" placeholder="Option ' + option_number + '">');
}
});
$("#poll_create").click(function() {
console.log("Button works");
var choices = new Array();
var counter = 0;
$("ul li input").each(function() {
choices[counter] = $(this).val();
counter++;
});
console.log(choices[1]);
console.log(choices[5]);
});
};

adding html from javascript but not working jQuery toggle function? [duplicate]

This question already has answers here:
jQuery doesn't work after content is loaded via AJAX
(9 answers)
Closed 9 years ago.
here is my js function to load html
function getLeftCategories() {
var id = 3;
$.getJSON("/api/kategori/getKategoriByTedarikci/" + id, function (data) {
var obj = jQuery.parseJSON(data);
$.each(obj, function () {
if (this.UstKategoriId == null) {
var kTop =
'<li>' +
'<a>' + this.KategoriAdi + '<span>+</span></a>' +
'<ul id="ulAltKategori">' +
'</ul>' +
'</li>'
$("#ulKategoriler").append(kTop);
}
});
$.each(obj, function () {
if (this.UstKategoriId != null) {
var sTop =
'<li>' +
'<a>- ' + this.KategoriAdi + '</a>' +
'</li>'
$("#ulAltKategori").append(sTop);
}
});
});
}
this is my html side
<div class="box">
<div class="box-heading">Kategoriler</div>
<div class="box-content">
<div class="box-category">
<ul id="ulKategoriler">
</ul>
</div>
</div>
here is my script function to toggle
$(function () {
$('.box-category a > span').each(function () {
if (!$('+ ul', $(this).parent()).length) {
$(this).hide();
}
});
$('.box-category a > span').click(function (e) {
debugger;
e.preventDefault();
$('+ ul', $(this).parent()).slideToggle();
$(this).parent().toggleClass('active');
$(this).html($(this).parent().hasClass('active') ? "-" : "+");
return false;
});
$('.filter-active span').click();
});
if i add the html from javascript toggle function is not working am i missing something which one is load to page first time ?
If this is dynamically loaded html then you will need event delegation to handle this
$(document).on('click', ".box-category a > span", function () {
...
}
Just change your script:
$('.box-category a > span').click(function (e) {
debugger;
e.preventDefault();
...
}
to
$('.box-category').on('click', 'a > span', function (e) {
debugger;
e.preventDefault();
e.stopPropagation();
...
}

Categories