Using the same jQuery functions but causing conflicts in HTML - javascript

Title - Sorry about the title, it was difficult for me to actually explain this.
So I recently finished working on a dynamic fields system using jQuery. This is all working great however I'm wanting to re-use the html for the system over and over again on the same page, this causes problems.
Problem
- When you have duplicates of the form on the same page, and you press 'Add Field' it will run the function and apply the functions to the other classes on the page. (See fiddle for example.)
When you just have one form on the DOM it works fine, but I'm wanting to alter the html slightly so I can use it for different scenarios on a page. I don't want to have separate jQuery files to do this because I don't think it's necessary. I was thinking maybe I could target it's parent containers instead of the class directly? Then I could recycle the same code maybe?
Any suggestions on this guys?
HTML:
<form action="javascript:void(0);" method="POST" autocomplete="off">
<button class="add">Add Field</button>
<div class='input_line'>
<input type="text" name="input_0" placeholder="Input1">
<input type="button" class="duplicate" value="duplicate">
<input type="button" class="remove" value="remove">
</div>
</form>
JQUERY:
$(document).ready(function () {
'use strict';
var input = 1,
blank_line = $('.input_line'),
removing = false;
$('.remove').hide();
$('.add').click(function () {
var newElement = blank_line.clone(true).hide();
$('form').append(newElement);
$(newElement).slideDown();
$('.remove').show();
});
$('form').on('click', '.duplicate', function () {
$(this).parent().clone().hide().insertAfter($(this).parent().after()).slideDown();
$('.input_line').last().before($('.add'));
$('.remove').show();
input = input + 1;
});
$('form').on('click', '.remove', function () {
if (removing) {
return;
} else {
if ($('.input_line').length <= 2) {
$('.remove').hide();
}
$(this).parent().slideUp(function () {
$(this).remove();
removing = false;
});
$('.input_line').last().before($('.add'));
input = input - 1;
}
removing = true;
});
});
Working fiddle - JSFiddle
Problem fiddle - JSFiddle
As you can see in the problem fiddle above, when you duplicate the form it start conflicting. I would like each form to work independently.
Any help would be greatly appreciated!

You need to use closest('form') to find the associated form. Also when looking up the other fields, you need to search within the context of the related form, http://jsfiddle.net/95vaaxsL/7/
function addLine($inputLine) {
var $form = $inputLine.closest('form');
var $newElement = $inputLine.clone(true).hide();
$newElement.insertAfter($inputLine);
$newElement.slideDown();
$form.find('.remove').show();
}
$(document).ready(function () {
'use strict';
$('.remove').hide();
$('.add').click(function () {
addLine($(this).closest('form').find('.input_line:last'));
});
$('form').on('click', '.duplicate', function () {
addLine($(this).closest('.input_line'));
});
$('form').on('click', '.remove', function () {
var $inputLine = $(this).closest('.input_line');
var $form = $inputLine.closest('form');
if ($form.find('.input_line').length < 3) {
$form.find('.remove').hide();
}
$inputLine.slideUp(function(){
$inputLine.remove();
});
});
});
Pulled out the function.

Related

Highlight input text not working

Hello I would like the text inside an input element to highlight upon initial click. However my function does not seem to be working. I have researched the issue and seen that there are some issues with jquery 1.7 and below. I have adjusted it to account for this any it still does not work.
Any help would be great. Thanks!
HTML
<input type="text" value="hello"/>
JS
$scope.highlightText = function() {
$("input[type='text']").on("click", function() {
$(this).select();
});
https://plnkr.co/edit/b7TYAFQNkhjE6lpRSWTR?p=preview
You need to actually call your method at the end of controller, otherwise the event is not bound.
https://plnkr.co/edit/a0BlekB8qTGOmWS8asIx?p=preview
... other code ...
$scope.highlightText = function () {
$("input[type='text']").on("click", function () {
$(this).select();
var test = $(this).parent();
console.log(test);
});
$("textarea").on("click", function () {
$(this).select();
});
};
$scope.highlightText();
};
To select the text inside an input you would simply call this.select() from onclick like shown below
<input type="text" onclick="this.select()" value="hello"/>

Run javascript after element is added to body

I have a <div> element that does not appear on the page unless some function is activated. I want to remove this <div> after it appears on the page.
how do I run my JavaScript code when and only when this <div> element is added ?
I am new at this and would appreciate some help. Thanks.
ps. element is generated by jquery and only has classname.
Detailed explanation:
I implementing a excel export in an existing web application.
I am using a form surrounding filters for search and a ajaxgrid gridstate.
This form is submitted to a controller that has the corresponding viewmodels.
My code for submitting the form is this:
$(function () {
$('div.btn-group #export-citizen-list').on('click', function () {
var gridstate = $('#citizenIndexGrid').ajaxgrid('getState');
var form = $('#create-citizen-csv-file');
// add ajaxgrid state to post data
$.each(gridstate, function (k, v) {
form.addAjaxgridHidden(k, v);
});
// submit entire form, with ajaxgrid state
form.submit();
// remove all hiddenfields that belongs to ajaxgrid
form.find(":hidden.ajaxgrid").remove();
document.getElementById("filterSearch").className = "default ui-button ui-widget ui-state-default ui-corner-all";
$('#filterSearch').removeAttr('disabled');
// function that removes unwanted <div> ---->$('.ajaxWorkingNotification').slideUp();
})
jQuery.fn.addAjaxgridHidden = function (name, value) {
return this.each(function () {
var input = $('<input>').attr('type', 'hidden').attr('name', name).attr('class', 'ajaxgrid').val(value);
$(this).append($(input));
});
};
});
When I submit my form the excel is downloaded and the unwanted <div> is inserted in the DOM. The thing is that I don't know when the postback is returned in this case. And therefore I don't know when this <div> is inserted.
Hope this clarifies my issue.
You can do something like this.
// Assuming your element is created by this line ...
$(".your_elements_class_name").ready(function() {
// write code here
// this is executed after the element is created and added to DOM
})
You can do it by implement a listener on DOM node insertion event.
There was an explanation here on how to detect DOM node insertion & pure javascript code to demonstrate how it works
And if you like a jQuery version, then here is the sample code that I translated from above link.
HTML:
<input type="button" id="addme" value="Add"/>
<div id="container">
</div>
CSS:
#keyframes nodeInserted {
from { opacity: 0.99; }
to { opacity: 1; }
}
#container div#mydiv {
animation-duration: 0.001s;
animation-name: nodeInserted;
}
Javascript:
$(function () {
$('#addme').click(function () {
var div = $('<div/>').attr('id', 'mydiv').html("Hello");
$('#container').append(div);
});
var handler = function (e) {
if (e.originalEvent.animationName == "nodeInserted")
alert("An HTMLElement has been inserted to DOM tree !")
};
var eventSignature = 'MSAnimationStart';
if ($.browser.webkit) eventSignature = 'webkitAnimationStart';
if ($.browser.mozilla) eventSignature = 'animationstart';
$(document).on(eventSignature, handler);
});
JSFiddle Demo

Getting the collection in a jQuery plugin

Basically, what I am trying to do is create a bbcode editor with a textbox, some buttons and jQuery. Here is my form:
<div class="form-group">
<div class="btn-group btn-group-sm">
<button type="button" class="btn glyphicon bbcode" rel="bold"><b>B</b></button>
<button type="button" class="btn glyphicon bbcode" rel="italic"><i>I</i></button>
</div>
</div>
<div class="form-group">
<textarea class="bbcode" rel="editor" cols="100" rows="12"></textarea>
</div>
and my plugin is called using:
<script>
$('document').ready(function() {
$('.bbcode').bbcode();
});
</script>
and the plugin itself, I am just trying to get the basics done at the minute to update the textbox data when a button is clicked:
(function($) {
"use strict";
$.fn.bbcode = function() {
this.click(function() {
var rel = $(this).attr('rel');
if (rel == 'editor') {
return this;
} else {
alert($(this).attr('rel')); // I can see this pop up so the click event is firing
$('.bbcode[rel=editor]').val('test');
return this;
}
});
}
} (jQuery));
This seems to be the only way I can pick up the textbox, I don't really want to hardcode the class I want like that. I think what I am looking for is a way to get the collection from the function call in the script tags.
This is more than likely something stupid/obvious I have overlooked.
The value of this in the immediate function refers to the collection. However, it is shadowed by the this inside your click handler (which refers to the element being clicked) so you cannot access it.
Create a variable to store this and that'll be your collection.
(function ($) {
"use strict";
$.fn.bbcode = function () {
var $editors = this;
this.click(function () {
var rel = $(this).attr('rel');
if (rel == 'editor') {
return this;
} else {
alert($(this).attr('rel')); // I can see this pop up so the click event is firing
$editors.val('test');
return this;
}
});
}
}(jQuery));

Two plugins in a textarea

I need to use two plug-ins in one element on my page. I've never needed to do this and tried as it is in the code below. Most did not work!
<script type="text/javascript">
$(document).ready(function()
{
var wbbOpt = {buttons: "bold,italic,underline,|,img,link,|,code,quote"}
// plugin one wysibb
$("#editor").wysibb(wbbOpt);
// plugin two hashtags
$("#editor").hashtags();
//the two plugin worked in textarea #editor
});
</script>
Can anyone help me? Thank you.
So you can't use them because each of them take control and wrap the textarea. Since the editor is the most complex of the two the best thing to do is to take the code of the hashtag and adapt it at your need.
So here's a working example, but if you want you can trigger the function I use to the change event (adding it) or some way else
<div id="higlighter" style="width;1217px;"></div>
<textarea id="editor"></textarea>
<br />
<input id="btn" type="button" value="HASH">
<br />
$(document).ready(function() {
var wbbOpt = {
buttons: "bold,italic,underline,|,img,link,|,code,quote"
};
$("#editor").wysibb(wbbOpt);
$('#btn').click(function () { report() });
});
function report() {
$("#hashtag").val($("#editor").htmlcode());
var str = $("#editor").htmlcode();
str = str.replace(/\n/g, '<br>');
if(!str.match(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,#?^=%&:\/~+#-]*[\w#?^=%&\/~+#-])?#([a-zA-Z0-9]+)/g)) {
if(!str.match(/#([a-zA-Z0-9]+)#/g)) {
str = str.replace(/#([a-zA-Z0-9]+)/g,'<span class="hashtag2">#$1</span>');
}else{
str = str.replace(/#([a-zA-Z0-9]+)#([a-zA-Z0-9]+)/g,'<span class="hashtag2">#$1</span>');
}
}
$("#editor").htmlcode(str);
}
you can check a working code here on jsfiddle.
http://jsfiddle.net/4kj7d6mh/2/
You can type your text and use the editor, and when you want to higlight the hastag you click the button. If you want that to happen automatically you have to change this line:
$('#btn').click(function () { report() });
And attach the function to the keypress for example (experiment a bit)

Setting A Limit On Input Field Creation?

I haven't found nothing on this topic so I though I quickly ask here.
Anyway I am creating a feature which allow users to add new admins to there clan and to make it easier the user can add a new input field that is all working fine ;)
But what I want is to only allow the user to add a maxim of 5 admins at one time to save server resources as at the moment they can have as many as they want.
How could I archive this?
(The code is below)
<form>
<input type="text" />
</form>
<button id="addFields">Add another field
</button>
//JQUERY SIDE BELOW
$(function ($) {
$('body').on("click", '#addFields', function () {
$('form').append('<input type="text" />')
})
})(jQuery)
client side you can do in this way
$(function ($) {
$('body').on("click", '#addFields', function () {
if ($("form > input:text").length < 5) {
$('form').append('<input type="text" />');
}
else{
alert('can't add more admins');
}
});
})(jQuery);
but in this way you are blocking only to add maximum 5 admins at the same time.
in your server side you should do something like this (a more robust solution) (SQL)
SET #admins= (SELECT COUNT(IdUSerAdmin) FROM Users where IdAdmin= #YouAdminUser)
IF(#admins < 5)
BEGIN
INSERT INTO USERS ....
END
What #Vote to Close said is right, you'll need to stop this on both the server and client side. On the client side, you could do this:
$(function ($) {
var MAX_LIMIT = 5;
$('body').on("click", '#addFields', function () {
if ($("form > input[type='text']").length < MAX_LIMIT) {
$('form').append('<input type="text" />');
}
});
})(jQuery);
$(function ($) {
var totalFieldsAdded = 0;
var totalFieldsAllowed = 5;
$('body').on("click", '#addFields', function () {
if(totalFieldsAdded < totalFieldsAllowed){
$('form').append('<input type="text" />');
totalFieldsAdded++;
}
})
})(jQuery)

Categories

Resources