Being able to edit data immediately is an awesome feature provided by two of my favorite web tools – Trello and JIRA. It is super easy to change information that might have been entered wrong, or simply needs updating. I often use this sort of element in my own applications so I decided to make a more reusable component with a JQuery plugin. I also love Twitter Bootstrap’s styling, so the plugin utilizes some of the styling.
First make a new file and name it inline-form.js.
There is a great tutorial for making JQuery plugins on their website that you might want to read over quickly. It will explain why there is a “(function($) {” wrapper around our code and give you some other useful insights into developing a plugin. This post will be dedicated to the details of this specific plugin.
First let’s take a look at what we want to build first. I want to be able to display an HTML element, like a piece of text that looks clickable (maybe a link), and when a user clicks on it, I want it to turn into a pre-populated text input with a submit and cancel button. You can view a demo of it here. You can download the source on github here
So first we will include some requisite code at the beginning of our plugin. You can read JQuery’s plugin tutorial if you are interested in what it does.
(function( $ ) {
$.fn.inlineForm = function(options) {
//Our code will go in here
};
}(JQuery));
So we want to be able to put an html element on the screen like this:
<a href="#" class="inline-form">Click this to edit the value</a>
And have it turn into a text input with some buttons. Since our plugin utilizes JQuery and bootstrap, our html will have to include those tools as well, but let’s focus on the JQuery plugin. So let’s begin with the basics. We need a hidden form that we will show when you click on the link, and we need to hide the link.
(function( $ ) {
$.fn.inlineForm = function(options) {
//First let's define the button for clarity
var button = $(this);
//Now let's define the basic behavior that we want to occur
$(button).click(function() {
$(button).hide();
$(form).show(); //Form isn't defined yet, we will get to that
});
};
}(JQuery));
The above code will make it so that when we click on the element, it will hide and a variable called “form” will show. Now we have to create the form to be shown. We could require it in the html and rely on the developer to include a hidden style and specify a target in the toggle button, or we could simply add it with our plugin.
(function( $ ) {
$.fn.inlineForm = function(options) {
//First let's define the button for clarity
var button = $(this);
//We are initializing these html elements as JQuery objects because we need to add behaviors to them
//This is the actual form object
var form = $("<form style='display:none'>", {
class: "col-xs-3",
id: settings.id,
action: settings.action,
method: settings.method,
html: "<button class='btn btn-default' style='border-radius:0px 0px 0px 5px;margin:-1px 0 0 10px;'><i class='glyphicon glyphicon-ok' style='color: green'></i></button>"
});
//This is the input that we will be putting default text into
var input = $("<input>", {
name: settings.name,
value: button.text(),
class: "form-control",
type: "text"
});
//This is a cancel button which we will add actions to that allows us to close the form and re-display the toggle button
var cancel = $("<span>", {
class: "btn btn-default cancel",
style: "border-radius:0px 0px 5px 0px; margin:-1px 0 0 -5px;",
form: "none",
html: "<i class='glyphicon glyphicon-remove' style='color: red'></i>"
});
//Now let's define the basic behavior that we want to occur
$(button).click(function() {
$(button).hide();
$(form).show(); //Form isn't defined yet, we will get to that
});
};
}(JQuery));
You’ll notice that I use an object called settings. There is a JQuery function that will allow us to accept a settings object (like many of JQuery’s methods) so that users can specify how they want our form to behave. Lets give the user the ability to specify a couple of things like the name of the input, the id of the input, the action in the form for when they submit, and the form method. We can do that by calling the $.extend method and placing its contents into a settings variable.
var settings = $.extend({
name: "name",
id: null,
action: null,
method: "post"
}, options);
Now we will be able to use settings.’member’ to access these data members within our code.
If you’re following along, you might have noticed that our form doesn’t actually appear yet. This is because we have created the JQuery objects for the form, but we haven’t placed them on the page. Let’s do that now. After you initialize the JQuery objects for the form, you can place the following code:
//Add the Input and Cancel buttons to the Form object
form.prepend(input);
form.append(cancel);
//Add the form to the DOM after the toggle button
button.after(form);
Now if we use our plugin, we should see an input with a couple of buttons below it show up. If you click the submit button it should send your form on its way to handle the data. However, if you click the cancel button, it won’t do anything. Let’s make it so clicking the cancel button will change everything back to the way it was.
$(cancel).click(function () {
//Change the input value back to the original value
$(input).val($(button).text());
//Hide the form and show the button
$(form).hide();
$(button).show();
});
The last thing we want to do is preserve JQuery’s ability to method chain. To do that all we have to do is return the JQuery object at the very end of our code block with “return this;”. Your code should look like the code below:
(function( $ ) {
$.fn.inlineForm = function(options) {
var button = $(this);
var settings = $.extend({
name: "name",
id: null,
action: null,
method: "post"
}, options);
//Initialize additional elements for the hidden form
var form = $("<form style='diplay:none'>", {
class: "col-xs-3",
id: settings.id,
action: settings.action,
method: settings.method,
html: "<button class='btn btn-default' style='border-radius:0px 0px 0px 5px;margin:-1px 0 0 10px;'><i class='glyphicon glyphicon-ok' style='color: green'></i></button>"
});
var input = $("<input>", {
name: settings.name,
value: button.text(),
class: "form-control",
type: "text"
});
var cancel = $("<span>", {
class: "btn btn-default cancel",
style: "border-radius:0px 0px 5px 0px; margin:-1px 0 0 -5px;",
form: "none",
html: "<i class='glyphicon glyphicon-remove' style='color: red'></i>"
});
//Add the input and cancel buttons to the form
form.prepend(input);
form.append(cancel);
//Add the form after the editable element
button.after(form);
//Hide the form when the cancel button is clicked and reset the value of the input
$(cancel).click(function () {
$(input).val($(button).text());
$(form).hide();
$(button).show();
});
//Display the form when the element is clicked
button.click(function() {
$(this).hide();
$(form).show();
});
//Return the button for JQuery chaining
return this;
};
}( jQuery ));
Now we can use our plugin by simply calling our function on a JQuery selector object:
$(".inline-form").inlineForm();
You can provide the function with a Javascript object of settings if you want to override any of the defaults that we specified in the settings variable.
$(".inline-form").inlineForm({
name: "form-input",
action: "formController/changeData.php",
method: "GET"
});
There you have it, a working inline form in JQuery!