Solved

jQuery input elements losing value upon adding item to list

Posted on 2009-05-19
19
1,544 Views
Last Modified: 2012-05-07
I have implemented a script to be able to add elements to a list and sort them. I can add them fine. I edited the script so that I could edit the elements name after being sent to the list by appending <input> inside the element created in the sort list..

Every time I add a new element to the list all the other input elements in the sort list lose their value.

I got the script from here:

The script here below isjquery.asmselect.js and the doc ready function on my page.
//this is the main script jquery.asmselect.js

/*

 * Alternate Select Multiple (asmSelect) 1.0.4 beta - jQuery Plugin

 * http://www.ryancramer.com/projects/asmselect/

 * 

 * Copyright (c) 2008 by Ryan Cramer - http://www.ryancramer.com

 * 

 * Dual licensed under the MIT (MIT-LICENSE.txt)

 * and GPL (GPL-LICENSE.txt) licenses.

 *

 */
 

(function($) {
 

	$.fn.asmSelect = function(customOptions) {
 

		var options = {
 

			listType: 'ol',						// Ordered list 'ol', or unordered list 'ul'

			sortable: false, 					// Should the list be sortable?

			highlight: false,					// Use the highlight feature? 

			animate: false,						// Animate the the adding/removing of items in the list?

			addItemTarget: 'bottom',				// Where to place new selected items in list: top or bottom

			hideWhenAdded: false,					// Hide the option when added to the list? works only in FF

			debugMode: false,					// Debug mode keeps original select visible 
 

			removeLabel: 'remove',					// Text used in the "remove" link

			highlightAddedLabel: 'Added: ',				// Text that precedes highlight of added item

			highlightRemovedLabel: 'Removed: ',			// Text that precedes highlight of removed item
 

			containerClass: 'asmContainer',				// Class for container that wraps this widget

			selectClass: 'asmSelect',				// Class for the newly created <select>

			optionDisabledClass: 'asmOptionDisabled',		// Class for items that are already selected / disabled

			listClass: 'asmList',					// Class for the list ($ol)

			listSortableClass: 'asmListSortable',			// Another class given to the list when it is sortable

			listItemClass: 'asmListItem',				// Class for the <li> list items

			listItemLabelClass: 'asmListItemLabel',			// Class for the label text that appears in list items

			inputItemLabelClass: 'asmInputItemLabel',			// Class for the label text that appears in list items

			removeClass: 'asmListItemRemove',			// Class given to the "remove" link

			highlightClass: 'asmHighlight',				// Class given to the highlight <span>

			listPageTypeClass: 'asmPageType'            // Class given to page type <span> added by Dale Larsen
 

			};
 

		$.extend(options, customOptions); 
 

		return this.each(function(index) {
 

			var $original = $(this); 				// the original select multiple

			var $container; 					// a container that is wrapped around our widget

			var $select; 						// the new select we have created

			var $ol; 						// the list that we are manipulating

			var buildingSelect = false; 				// is the new select being constructed right now?

			var ieClick = false;					// in IE, has a click event occurred? ignore if not

			var ignoreOriginalChangeEvent = false;			// originalChangeEvent bypassed when this is true
 

			function init() {
 

				// initialize the alternate select multiple
 

				// this loop ensures uniqueness, in case of existing asmSelects placed by ajax (1.0.3)

				while($("#" + options.containerClass + index).size() > 0) index++; 
 

				$select = $("<select></select>")

					.addClass(options.selectClass)

					.attr('name', options.selectClass + index)

					.attr('id', options.selectClass + index); 
 

				$selectRemoved = $("<select></select>"); 
 

				$ol = $("<" + options.listType + "></" + options.listType + ">")

					.addClass(options.listClass)

					.attr('id', options.listClass + index); 
 

				$container = $("<div></div>")

					.addClass(options.containerClass) 

					.attr('id', options.containerClass + index); 
 

				buildSelect();
 

				$select.change(selectChangeEvent)

					.click(selectClickEvent); 
 

				$original.change(originalChangeEvent)

					.wrap($container).before($select).before($ol);
 

				if(options.sortable) makeSortable();
 

				if($.browser.msie) $ol.css('display', 'inline-block'); 

			}
 

			function makeSortable() {
 

				// make any items in the selected list sortable

				// requires jQuery UI sortables, draggables, droppables
 

				$ol.sortable({

					items: 'li.' + options.listItemClass,

					handle: '.' + options.listItemLabelClass,

					axis: 'y',

					update: function(e, data) {
 

						var updatedOptionId;
 

						$(this).children("li").each(function(n) {
 

							$option = $('#' + $(this).attr('rel')); 
 

							if($(this).is(".ui-sortable-helper")) {

								updatedOptionId = $option.attr('id'); 

								return;

							}
 

							$original.append($option); 

						}); 
 

						if(updatedOptionId) triggerOriginalChange(updatedOptionId, 'sort'); 

					}
 

				}).addClass(options.listSortableClass); 

			}
 

			function selectChangeEvent(e) {

				

				// an item has been selected on the regular select we created

				// check to make sure it's not an IE screwup, and add it to the list
 

				if($.browser.msie && $.browser.version < 7 && !ieClick) return;

				var id = $(this).children("option:selected").slice(0,1).attr('rel'); 

				addListItem(id); 	

				ieClick = false; 

				triggerOriginalChange(id, 'add'); // for use by user-defined callbacks

			}
 

			function selectClickEvent() {
 

				// IE6 lets you scroll around in a select without it being pulled down

				// making sure a click preceded the change() event reduces the chance

				// if unintended items being added. there may be a better solution?
 

				ieClick = true; 

			}
 

			function originalChangeEvent(e) {
 

				// select or option change event manually triggered

				// on the original <select multiple>, so rebuild ours
 

				if(ignoreOriginalChangeEvent) {

					ignoreOriginalChangeEvent = false; 

					return; 

				}
 

				$select.empty();

				$ol.empty();

				buildSelect();
 

				// opera has an issue where it needs a force redraw, otherwise

				// the items won't appear until something else forces a redraw

				if($.browser.opera) $ol.hide().fadeIn("fast");

			}
 

			function buildSelect() {
 

				// build or rebuild the new select that the user

				// will select items from
 

				buildingSelect = true; 
 

				// add a first option to be the home option / default selectLabel

				$select.prepend("<option>" + $original.attr('title') + "</option>"); 
 

				$original.children("option").each(function(n) {
 

					var $t = $(this); 

					var id; 
 

					if(!$t.attr('id')) $t.attr('id', 'asm' + index + 'option' + n); 

					id = $t.attr('id'); 
 

					if($t.is(":selected")) {

						addListItem(id); 

						addSelectOption(id, true); 						

					} else {

						addSelectOption(id); 

					}

				});
 

				if(!options.debugMode) $original.hide(); // IE6 requires this on every buildSelect()

				selectFirstItem();

				buildingSelect = false; 

			}
 

			function addSelectOption(optionId, disabled) {
 

				// add an <option> to the <select>

				// used only by buildSelect()
 

				if(disabled == undefined) var disabled = false; 
 

				var $O = $('#' + optionId); 

				var $option = $("<option>" + $O.text() + "</option>")

					.val($O.val())

					.attr('rel', optionId);
 

				if(disabled) disableSelectOption($option); 
 

				$select.append($option); 

			}
 

			function selectFirstItem() {
 

				// select the firm item from the regular select that we created
 

				$select.children(":eq(0)").attr("selected", true); 

			}
 

			function disableSelectOption($option) {
 

				// make an option disabled, indicating that it's already been selected

				// because safari is the only browser that makes disabled items look 'disabled'

				// we apply a class that reproduces the disabled look in other browsers
 

				$option.addClass(options.optionDisabledClass)

					.attr("selected", false)

					.attr("disabled", true);
 

				if(options.hideWhenAdded) $option.hide();

				if($.browser.msie) $select.hide().show(); // this forces IE to update display

			}
 

			function enableSelectOption($option) {
 

				// given an already disabled select option, enable it
 

				$option.removeClass(options.optionDisabledClass)

					.attr("disabled", false);
 

				if(options.hideWhenAdded) $option.show();

				if($.browser.msie) $select.hide().show(); // this forces IE to update display

			}
 

			function addListItem(optionId) {
 

				// add a new item to the html list
 

				var $O = $('#' + optionId); 
 

				if(!$O) return; // this is the first item, selectLabel
 

				var $removeLink = $("<a></a>")

					.attr("href", "#")

					.addClass(options.removeClass)

					.prepend(options.removeLabel)

					.click(function() { 

						dropListItem($(this).parent('li').attr('rel')); 

						return false;

					}); 
 

				var $itemInput = $('<input type="text"/>')

					.addClass(options.inputItemLabelClass)

					.val("");
 

				var $itemLabel = $('<span></span>')

					.append($itemInput)

					.addClass(options.listItemLabelClass);
 

				var $itemPageType = $('<span></span>')

					.addClass(options.listPageTypeClass)

					.html($O.html());

					

				var $item = $("<li></li>")

					.attr('rel', optionId)

					.addClass(options.listItemClass)

					.append($itemLabel)

					.append($itemPageType)

					.append($removeLink)

					.hide();
 

				if(!buildingSelect) {

					if($O.is(":selected")) return; // already have it

					$O.attr('selected', true); 

				}
 

				if(options.addItemTarget == 'top' && !buildingSelect) {

					$ol.prepend($item); 

					if(options.sortable) $original.prepend($O); 

				} else {

					$ol.append($item); 

					if(options.sortable) $original.append($O); 

				}
 

				addListItemShow($item); 
 

				disableSelectOption($("[rel=" + optionId + "]", $select));
 

				if(!buildingSelect) {

					setHighlight($item, options.highlightAddedLabel); 

					selectFirstItem();

					if(options.sortable) $ol.sortable("refresh"); 	

				}
 

			}
 

			function addListItemShow($item) {
 

				// reveal the currently hidden item with optional animation

				// used only by addListItem()
 

				if(options.animate && !buildingSelect) {

					$item.animate({

						opacity: "show",

						height: "show"

					}, 150, "swing", function() { //default 100

						$item.animate({

							height: "+=2px"

						}, 100, "swing", function() {//default 50

							$item.animate({

								height: "-=2px"

							}, 95, "swing");//default 25 

						}); 

					}); 

				} else {

					$item.show();

				}

			}
 

			function dropListItem(optionId, highlightItem) {
 

				// remove an item from the html list
 

				if(highlightItem == undefined) var highlightItem = true; 

				var $O = $('#' + optionId); 
 

				$O.attr('selected', false); 

				$item = $ol.children("li[rel=" + optionId + "]");
 

				dropListItemHide($item); 

				enableSelectOption($("[rel=" + optionId + "]", options.removeWhenAdded ? $selectRemoved : $select));
 

				if(highlightItem) setHighlight($item, options.highlightRemovedLabel); 
 

				triggerOriginalChange(optionId, 'drop'); 

				

			}
 

			function dropListItemHide($item) {
 

				// remove the currently visible item with optional animation

				// used only by dropListItem()
 

				if(options.animate && !buildingSelect) {
 

					$prevItem = $item.prev("li");
 

					$item.animate({

						opacity: "hide",

						height: "hide"

					}, 120, "linear", function() {//default 100

						$prevItem.animate({

							height: "-=2px"

						}, 70, "swing", function() {//default 50

							$prevItem.animate({

								height: "+=2px"

							}, 120, "swing"); //default 100

						}); 

						$item.remove(); 

					}); 

					

				} else {

					$item.remove(); 

				}

			}
 

			function setHighlight($item, label) {
 

				// set the contents of the highlight area that appears

				// directly after the <select> single

				// fade it in quickly, then fade it out
 

				if(!options.highlight) return; 
 

				$select.next("#" + options.highlightClass + index).remove();
 

				var $highlight = $("<span></span>")

					.hide()

					.addClass(options.highlightClass)

					.attr('id', options.highlightClass + index)

					.html(label + $item.children("." + options.listItemLabelClass).slice(0,1).text()); 

					

				$select.after($highlight); 
 

				$highlight.fadeIn(200, function() {//defalut "fast"

					setTimeout(function() { $highlight.fadeOut("slow"); }, 100);//default 50

				}); 

			}
 

			function triggerOriginalChange(optionId, type) {
 

				// trigger a change event on the original select multiple

				// so that other scripts can pick them up
 

				ignoreOriginalChangeEvent = true; 

				$option = $("#" + optionId); 
 

				$original.trigger('change', [{

					'option': $option,

					'value': $option.val(),

					'id': optionId,

					'item': $ol.children("[rel=" + optionId + "]"),

					'type': type

				}]); 

			}
 

			init();

		});

	};
 

})(jQuery); 
 
 

//this is the doc ready function that goes on my page.

$(document).ready(function() {

	$("div[multiple]").asmSelect({

		addItemTarget: 'bottom',

		animate: true,

		removeLabel: 'X',

		highlight: false,

		sortable: true

	});
 

	$("#add_blank_btn").click(function() {

		var addBlank = $("#add_blank").val();

		var $option = $("<option></option>").text(addBlank).attr("selected", true);

		$("#pages").append($option).change();

		return false;

	});

	$("#add_about_btn").click(function() {

		var addAbout = $("#add_about").val();

		var $option = $("<option></option>").text(addAbout).attr("selected", true);

		$("#pages").append($option).change();

		return false;

	});

	$("#add_articles_btn").click(function() {

		var addArticles = $("#add_articles").val();

		var $option = $("<option></option>").text(addArticles).attr("selected", true);

		$("#pages").append($option).change();

		return false;

	});

	$("#add_calendar_btn").click(function() {

		var addCalendar = $("#add_calendar, #add_contact, #add_hours, #add_jobs, #add_news, #add_press, #add_support").val();

		var $option = $("<option></option>").text(addCalendar).attr("selected", true);

		$("#pages").append($option).change();

		return false;

	});

	$("#add_contact_btn").click(function() {

		var addContact = $("#add_contact").val();

		var $option = $("<option></option>").text(addContact).attr("selected", true);

		$("#pages").append($option).change();

		return false;

	});

	$("#add_faq_btn").click(function() {

		var addFaq = $("#add_faq").val();

		var $option = $("<option></option>").text(addFaq).attr("selected", true);

		$("#pages").append($option).change();

		return false;

	});

	$("#add_hours_btn").click(function() {

		var addHours = $("#add_hours").val();

		var $option = $("<option></option>").text(addHours).attr("selected", true);

		$("#pages").append($option).change();

		return false;

	});

	$("#add_jobs_btn").click(function() {

		var addJobs = $("#add_jobs").val();

		var $option = $("<option></option>").text(addJobs).attr("selected", true);

		$("#pages").append($option).change();

		return false;

	});

	$("#add_news_btn").click(function() {

		var addNews = $("#add_news").val();

		var $option = $("<option></option>").text(addNews).attr("selected", true);

		$("#pages").append($option).change();

		return false;

	});

	$("#add_press_btn").click(function() {

		var addPress = $("#add_press").val();

		var $option = $("<option></option>").text(addPress).attr("selected", true);

		$("#pages").append($option).change();

		return false;

	});

	$("#add_support_btn").click(function() {

		var addSupport = $("#add_support").val();

		var $option = $("<option></option>").text(addSupport).attr("selected", true);

		$("#pages").append($option).change();

		return false;

	});

	

});

Open in new window

0
Comment
Question by:the_hero
  • 10
  • 9
19 Comments
 
LVL 18

Expert Comment

by:wilq32
Comment Utility
line 260:                        var $itemInput = $('<input type="text"/>')
                              .addClass(options.inputItemLabelClass)
                              .val("");



you have .val("")   ?? What for ? can you remove it ?



0
 
LVL 1

Author Comment

by:the_hero
Comment Utility
Thanks for the reply.

Sorry, that was a test I was doing to try and fix this. I now removed that line, it still has the same problem.
0
 
LVL 18

Expert Comment

by:wilq32
Comment Utility
what about removing


.html($O.html());

?:]
0
 
LVL 1

Author Comment

by:the_hero
Comment Utility
thanks, but still not working with that change...
0
 
LVL 1

Author Comment

by:the_hero
Comment Utility
I think that the element is being refreshed or something when I append a new element to the list, or I could be wrong.

Is there a way to hold an elements value so that it is no lost, or a way that when someone appends a new element to the list it take the values of the inputs and reassigns them?
0
 
LVL 18

Expert Comment

by:wilq32
Comment Utility
well yes you could save that value, but if values beeing removed after adding new one.. then it means that they are all removed and added again. And this should not be like this... hmm... we could also store values but this is a bad idea (like hacking instead of good programming)
0
 
LVL 1

Author Comment

by:the_hero
Comment Utility
Yeah, I prefer to avoid hacking.
0
 
LVL 18

Expert Comment

by:wilq32
Comment Utility
Can you give me some example page on web with code running ? That would help me debug it ;)
0
 
LVL 1

Author Comment

by:the_hero
Comment Utility
Alright, I have made this test page.

Go to:
http://dalelarsen.com/fab/sort.php
0
Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

 
LVL 18

Expert Comment

by:wilq32
Comment Utility
Look at function buildSelect - as there in comments it just builds or rebuilds whole select element.

You just need to:

Put there (exacly in addListItem (optionId)) a proper value that will be stored before removing every elements in this list.


Removing elements is here:

function originalChangeEvent(e) {

...

$select.empty();
$ol.empty();
buildSelect();




Is this enough here for you ?
0
 
LVL 1

Author Comment

by:the_hero
Comment Utility
Thank you so much, but I am afraid I'm not sure what to add or delete? I'll keep looking into it but I'm a bit confused.
0
 
LVL 18

Expert Comment

by:wilq32
Comment Utility
originalChangeEvent is a function that is fired when you trying to add new input. It just removes all inputs that you had before and create a whole new list (buildSelect function do that using an addListItem function). So what you can do is to store input values in originalChangeEvent just before removing elements and then  use this value to fill proper data inside addListItem function. Is that sount clear ? Or still have problem ?:)
0
 
LVL 1

Author Comment

by:the_hero
Comment Utility
Thanks, Sounds clear, I'm just not that advanced with javascript...
0
 
LVL 18

Accepted Solution

by:
wilq32 earned 500 total points
Comment Utility
Before $select.empty()  do:


$("#asmList0 li").each(function()
{
var value=($("input",this).attr("value"));

$("#"+this.getAttribute('rel')).attr("last",value);
});



then in addListItem do that:

change this:

 var $itemInput = $('<input type="text"/>').addClass(options.inputItemLabelClass);



to:


 var $itemInput = $('<input type="text"/>').addClass(options.inputItemLabelClass).value = $O.attr("last");
0
 
LVL 1

Author Comment

by:the_hero
Comment Utility
Wow, thanks. I have implemented those changes. Now the appended element has no input field and I don't see why. I have tested it through it seems all the elements are there to create it.

When I remove:

.value = $O.attr("last");

From:

var $itemInput = $('<input type="text"/>')
.addClass(options.inputItemLabelClass)
.value = $O.attr("last");

The input fields show again but, of course, still without the desired functionality.

The updates have been made to the test page:

http://dalelarsen.com/fab/sort.php
0
 
LVL 18

Expert Comment

by:wilq32
Comment Utility
sorry Mine mistake

should be

var $itemInput = $('<input type="text"/>').addClass(options.inputItemLabelClass).attr("value",$O.attr("last"));
0
 
LVL 18

Assisted Solution

by:wilq32
wilq32 earned 500 total points
Comment Utility
Or a

var $itemInput = $('<input type="text"/>').addClass(options.inputItemLabelClass);
$itemInput.attr("value",$O.attr("last"));

if still got problem
0
 
LVL 1

Author Closing Comment

by:the_hero
Comment Utility
Perfect thanks!!!
0
 
LVL 1

Author Comment

by:the_hero
Comment Utility
Wilq, I need help at the following question that relates to this one. I need to do the same thing but detect if the radio was checked or not.

http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Jquery/Q_24574082.html
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

How to build a simple, quick and effective accordion menu using just 15 lines of jQuery and 2 css classes
This article demonstrates how to create a simple responsive confirmation dialog with Ok and Cancel buttons using HTML, CSS, jQuery and Promises
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now