How can I clone the form ( address input) ? not working
how to fix this problem
I want to do in such a way as when the user deletes the input and then add it, it should be an active input again. https://jsfiddle.net/joio/95o0wyfy/29
$('.add_input').eq(0).click(function() {
form_a++;
var formhtml = $('#divform_a .form').eq(0).html().toString();
formhtml = formhtml.replace(/form_a/g, 'form_item'+form_a);
$('#divform_a').eq(0).append('<div class="form">' + formhtml + '</div>');
focus_map_location = jQuery('#divform_a .form:last .map_location');
$("#divform_a .form:last .address").removeAttr('id');
address_form = $("#address").parent();
$("#address").clone(true).prependTo(address_form).removeAttr('id');
address_name = $("#divform_a .form:last .address").attr('name');
$("#divform_a .form:last .address").remove();
$("#address").prependTo($("#divform_a .form:last")).attr('name',address_name).val('');
});
Your problem seems to be in these two lines
address_form = $("#address").parent();
$("#address").clone(true).prependTo(address_form).removeAttr('id');
Your code does not set id to the newly created input tags. Once you delete the original element with the id, the prepen stops working. Also, this seems a lot more complicated than it should be.
This is all that it takes to duplicate (and also to get the name tag working)
$('.add_input').click(function() {
form_a++;
var copiedForm = $('#divform_a .form').eq(0).clone();
copiedForm.attr('name', 'form_item'+form_a);
$('#divform_a').append(copiedForm);
});
Fiddle
EDIT:
Here's your fiddle with minimal changes. The following line at the end, reinstates the #address to the first input and now the copy function works as it should
$("#divform_a .form:first .address").attr('id', 'address');
I would still advise to take a look at the code in the first fiddle and try to clean up. Or at the very least, learn from it :)
Second Edit:
In your map fiddle, you're initializing autocomplete only for the first field. You should do something like this
$('.address').each(function(){
var autocomplete = new google.maps.places.Autocomplete(this);
autocomplete.bindTo('bounds', map);
autocomplete.setTypes([]);
google.maps.event.addListener(autocomplete,'place_changed', function() {
infowindow.close();
markerPoint.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
});
});
});
This will make an Autocomplete of both fields. The clone's automatically pick up the property.
Related
I am creating a form dynamically and therefore edit the form elements’ properties. When attempting to change the label, assigning an auto-generated id works fine but when changing this label using the generated id, the function or keyup() from jQuery keeps calling all the previously created label id(s). this means when i want to edit one label, it ends up editing every label.
HTML
<input type="text" id="change-label"><br><br>
<button id="add-button">add label</button>
<div id="add-label"></div>
JavaScript/jQuery
$('#add-button').click(function(){
var div = document.createElement('div');
var textLabel = document.createElement('label');
var labelNode = document.createTextNode('untitled');
textLabel.appendChild(labelNode);
textLabel.id = autoIdClosure();
$('#change-label').val('untitled');
div.appendChild(textLabel);
$('#add-label').append(div);
});
var autoIdClosure = (function(){
var counter = 0;
var labelId = "textInputLabel";
return function(){
counter += 1;
var id = labelId + counter;
editLabelWrapper(id)
return id;
}
})();
function editLabelWrapper(id){
function editLabel(){
var value = $(this).val();
$("#"+id).text(value);
}
$("#change-label").keyup(editLabel).keyup();
}
I’ve already found an alternative using onkeyup="$('#'+globaID).text($(this).val());", but I need to understand what I was doing wrong so I can learn from it.
JSFiddle
I think you are overthinking the matter...
Instead of using an unique id, rather use classes, makes it easier to handle.
So change <div id="add-label"></div> to <div class="add-label"></div>
Then what you want to do is, when a value is given in #change-label you want it in the last div.add-label.
So the function will become this:
$("#change-label").on('keyup', function() {
$('.add-label:last').text( $(this).val() );
});
Next what you want to do is bind a function to #add-button. Once it gets clicked, we want to add a new div.add-label after the last one. And empty the #change-label. You can do that by using this function:
$('#add-button').on('click', function() {
$('.add-label:last').after('<div class="add-label"></div>');
$('#change-label').val('');
});
Updated Fiddle
everybody.
I have a little problem; I'm trying to build a WYSIWYG, but I encountered some problems.
I have a contenteditable div with id = desc2, and some buttons. Let's take, for example, the button "bold".
<div class="magic" magic_id="desc2">
<div class="magicbutton one" magic="[b]%s[/b]">
<span style="font-weight:bold;">Bold</span>
</div>
</div>
And I have some jQuery++ selection application in:
$('#desc2').on('mouseup', function() {
var selection = $(this).selection(),
text = $(this).text().substring(selection.start, selection.end);
console.log(text);
});
I have erased the other part of the script, because if I manage to get this to work, I'm done :D
So, as I was saying, if I do this, everything is good: I sleect a part on the div and on the console is outputted the content.
But this is not what I want to do. I wrote this:
$('.magicbutton.uno').on('click', function(){
var id = $(this).parent().attr("magic_id");
var selection = $("#"+id).selection(),
text = $("#"+id).text().substring(selection.start, selection.end);
console.log(text);
});
Everytime I click, it takes the ID of the div to change and should output the selected text, but it doesn't.
The code is the same, and i checked that $(this) in the first script is the same as $("#"+id) in the second.
What can I do? Thanks!
EDIT: jsFiddle
When DIV loses focus, selection is nullified. As a workaround, you could use data object:
DEMO
$('.magicbutton.one').on('click', function(){
var id = $(this).parent().attr("magic_id"); //id = desc2, i used this because i could have multiple forms in a page
var selection = $("#"+id).data('selection');
alert(selection);
}); //This doesn't work
$('#desc2').on('mouseup', function() {
var selection = $(this).selection(),
text = $(this).text().substring(selection.start, selection.end);
$(this).data('selection', text);
});
I am using angularjs, please see this code in http://jsfiddle.net/6XDeV/
what I want:
When click on the button add it will appear $scope.todotest value a long with the value in textbox.
My problem:
When I add the first it not show the date along with the text in textbox and if I add the second time it will appear. And I want to appear since the first time that click on add button.
Anyone know about this help me to fix please, thanks.
That's because at the first time you call addTodo the todotest is undefined.
Just move the $scope.todotest = '23' before the push, like this:
$scope.addTodo = function() {
$scope.todotest = '23';
$scope.todos.push({text:$scope.todoText,test:$scope.todotest, done:false});
$scope.todoText = '';
};
Example: http://jsfiddle.net/757d3/
You're setting the $scope variable todotest after adding a new item to your array todos.
$scope.addTodo = function() {
$scope.todos.push({text:$scope.todoText,test:$scope.todotest, done:false});
$scope.todoText = '';
$scope.todotest = '23'; // This should be done before the push
};
See updated fiddler here.
add this line $scope.todotest = '23'; before this $scope.addTodo = function() {
check this[code] http://jsfiddle.net/6XDeV/1/[/code]
I have the following fiddle:
http://jsfiddle.net/XpAk5/63/
The IDs increment appropriately. For the first instance. The issue is when I try to add a sport, while it duplicates, it doesn't duplicate correctly. The buttons to add are not creating themselves correctly. For instance, if I choose a sport, then fill in a position, and add another position, that's all fine (for the first instance). But when I click to add another sport, it shows 2 positions right away, and the buttons aren't duplicating correctly. I think the error is in my HTML, but not sure. Here is the JS I am using to duplicate the sport:
$('#addSport').click(function(){
//increment the value of our counter
$('#kpSport').val(Number($('#kpSport').val()) + 1);
//clone the first .item element
var newItem = $('div.kpSports').first().clone();
//recursively set our id, name, and for attributes properly
childRecursive(newItem,
// Remember, the recursive function expects to be able to pass in
// one parameter, the element.
function(e){
setCloneAttr(e, $('#kpSport').val());
});
// Clear the values recursively
childRecursive(newItem,
function(e){
clearCloneValues(e);
});
Hoping someone has an idea, perhaps I've just got my HTML elements in the wrong order? Thank you for your help! I'm hoping the fiddle is more helpful than just pasting a bunch of code here in the message.
The problem is in your clearCloneValues function. It doesn't differentiate between buttons and other for elements that you do want to clear.
Change it to:
// Sets an element's value to ''
function clearCloneValues(element){
if (element.attr('value') !== undefined && element.attr('type') !== 'button'){
element.val('');
}
}
As #PHPglue pointed out in the comments above, when new positions are added, they are incorrectly replicated (I'm assuming here) to the newly cloned for
There is a similar problem with the add years functionality.
A quick fix would be to initialize a variable with a clone of the original form fields:
var $template = $('div.kpSports').first().clone();
Then change your addSport handler to:
$('#addSport').click(function () {
//increment the value of our counter
$('#kpSport').val(Number($('#kpSport').val()) + 1);
//clone the first .item element
var newItem = $template.clone();
…
});
However, there are no event bindings for the new buttons, so that functionality is still missing for any new set of form elements.
Demo fiddle
Using even a simple, naive string based templates the code can be simplified greatly. Linked is an untested fiddle that shows how it might be done using this approach.
Demo fiddle
The code was simplified to the following:
function getClone(idx) {
var $retVal = $(templates.sport.replace(/\{\{1\}\}/g, idx));
$retVal.find('.jsPositions').append(getItemClone(idx, 0));
$retVal.find('.advtrain').append(getTrainingClone(idx, 0));
return $retVal;
}
function getItemClone(setIdx, itemIdx) {
var retVal = itemTemplate.replace(/\{\{1\}\}/g, setIdx).replace(/\{\{2\}\}/g, itemIdx);
return $(retVal);
}
function getTrainingClone(setIdx, trainingIdx) {
var retVal = trainingTemplate.replace(/\{\{1\}\}/g, setIdx).replace(/\{\{2\}\}/g, trainingIdx);
return $(retVal);
}
$('#kpSportPlayed').on('click', '.jsAddPosition', function() {
var $container = $(this).closest('.kpSports');
var containerIdx = $container.attr('data_idx');
var itemIdx = $container.find('.item').length;
$container.find('.jsPositions').append(getItemClone(containerIdx, itemIdx));
});
$('#kpSportPlayed').on('click', '.jsAddTraining', function() {
var $container = $(this).closest('.kpSports');
var containerIdx = $container.attr('data_idx');
var trainIdx = $container.find('.advtrain > div').length;
$container.find('.advtrain').append(getTrainingClone(containerIdx, trainIdx));
});
$('#addSport').click(function () {
var idx = $('.kpSports').length;
var newItem = getClone(idx);
newItem.appendTo($('#kpSportPlayed'));
});
Made a fiddle: http://jsfiddle.net/n6ub3/
I'm aware that the code has a LOT of repeating in it, its on the list to refactor once functionality is correct.
The behaviour i'm trying to achieve is if there is no selectedTab on page load, set the first tab in each group to selectedTab. If there is a selectedTab present, then use this as the default shown div.
However, as you can see from the fiddle its not working as planned!
If anyone has any ideas how to refactor this code down that'd be great also!
Change
if($('.tabs1 .tabTrigger:not(.selectedTab)')){
$('.tabs1 .tabTrigger:first').addClass('selectedTab');
}
to
if ( !$('.tabs1 .tabTrigger.selectedTab').length ) {
$('.tabs1 .tabTrigger:first').addClass('selectedTab');
}
Demo at http://jsfiddle.net/n6ub3/1/
They way you are doing it (the first code part) you are adding the .selectedTab class if there is at least one of the tabs in that group that is not selected at start .. (that means always)
Update
For a shortened version look at http://jsfiddle.net/n6ub3/7/
Your selector are doing exactly what you're writing them for.
$('.tabs3 .tabTrigger:not(.selectedTab)') is true has long as there is at least one tab that has not the selected tab (so always true in your test case).
So you should change the logic to !$('.tabs3 .tabTrigger.selectedTab').length which is true only if there are no selectedTab
WORKING DEMO with simplified code
$('.tabContent').hide();
$('.tabs').each(function(){
var search = $(this).find('div.selectedTab').length;
if( search === 0){
$(this).find('.tabTrigger').eq(0).addClass('selectedTab')
}
var selectedIndex = $(this).find('.selectedTab').index();
$(this).find('.tabContent').eq(selectedIndex).show();
});
$('.tabTrigger').click(function(){
var ind = $(this).index();
$(this).addClass('selectedTab').siblings().removeClass('selectedTab');
$(this).parent().find('.tabContent').eq(ind).fadeIn(700).siblings('.tabContent').hide();
});
That's all! You don't need all that ID's all around. Look at the demo!
With a couple of very minor changes you code can be reduced to:
$('.tabContent').hide();
$('.tabs').each(function(){
if($('.tabTrigger.selectedTab',$(this)).length < 1)
$('.tabTrigger:first').addClass('selectedTab');
});
$('.tabTrigger').click(function(){
var content = $(this).data('content');
$(this).parents('div').children('.tabContent').hide();
$(this).parents('div').children('.tabTrigger').removeClass('selectedTab');
$(this).addClass('selectedTab');
$('#' + content).show();
});
$('.tabTrigger.selectedTab').click();
Those changes are
Change the class on the surrounding div to just class="tabs.
Add a data-content attribute with the name of the associated content div
Live example: http://jsfiddle.net/gsTBQ/
Well, I'm a bit behind the times obviously; but, here's my updated version of your demo...
I have updated your fiddle as in the following fiddle: http://jsfiddle.net/4y3Xp/1/.
Basically I just tidied it up a bit, and to refactor I put everything in a separate function instead of having each of the cases in their own. This is basically just putting a new function in that does similar to what yours was doing (e.g. not modifying your HTML model), but I tried to clean it up a bit, and I also just made a function that took the tab number and did each of the items that way rather than needing a separate copy for each.
The main issue with the 'not' part of your query is that the function doesn't return a boolean; like all JQuery queries, it's returning all matching nodes. I just updated that part to return whether .selected was returning more than 0 results; if not, I go ahead and call the code to select the first panel.
Glad you got your problem resolved :)
$(document).ready(function(){
var HandleOne = function (i) {
var idxString = i.toString();
var tabName = '.tabs' + idxString;
var tabContent = tabName + ' .tabContent';
$(tabContent).hide();
var hasSelected = $(tabName + ' .tabTrigger.selectedTab').length > 0;
if (!hasSelected)
$(tabName + ' .tabTrigger:first').addClass('selectedTab');
var selectedTabId =
$(tabName + ' .tabTrigger.selectedTab').attr('id');
var selectedContentId = selectedTabId.replace('tab','content');
$('#' + selectedContentId).show();
$(tabName + ' .tabTrigger').click(function() {
$(tabName + ' .tabTrigger').removeClass('selectedTab');
$(tabName + ' .tabContent').hide();
$(this).addClass('selectedTab');
var newContentId = $(this).attr('id').replace('tab','content');
$('#' + newContentId).show();
});
}
HandleOne(1);
HandleOne(2);
HandleOne(3);
});