将外部对象添加到现有阵列

时间:2017-04-11 10:39:03

标签: jquery arrays json dom dynamic

我有一张基于JSON数据更新的表格。 表中的每一行都有一个复选框,其中包含相应JSON对象的值,该对象基本上是关于任何用户的信息。 在选择任何行并保存以显示所选用户配置文件时,我还将所选JSON对象存储在数组' savedData'。

我还可以选择通过点击“打开外部表单”弹出的表单在外部添加用户。按钮。现在,我尝试创建一个对象并将其存储在同一个“已保存的数据”中。提交该表单的数组。与此同时,' div.parent'应该生成&附加到' div.container'格式与从表格中选择的其他用户的格式相同。

不幸的是,' div.parent'没有被创建,外部对象没有被添加。

你可以帮我解决这个问题吗?



function createTable() {
			$.getJSON("https://api.randomuser.me/?results=5", function(data) {
				$('#datatable tr:has(td)').remove();
				data.results.forEach(function (record) {
					var json = JSON.stringify(record);
					$('#datatable').append(
						$('<tr>').append(
							$('<td>').append(
								$('<input>').attr('type', 'checkbox')
											.addClass('selectRow')
											.val(json)
							),
							$('<td>').append(
								$('<a>').attr('href', record.picture.thumbnail)
										.addClass('imgurl')
										.attr('target', '_blank')
										.text(record.name.first)
							),
							$('<td>').append(record.dob)
						)
					);
				})
			}).fail(function(error) {
				console.log("**********AJAX ERROR: " + error);
			});            
		}

		var savedData = new Map; // Keyed by image URL. Start with nothing.

		function saveData(){
			var errors = [];
			// Add selected to map
			$('input.selectRow:checked').each(function(count) {
				// Get the JSON that is stored as value for the checkbox
				var obj = JSON.parse($(this).val());
				// See if this URL was already collected (that's easy with Set)
				if (savedData.get(obj.picture.thumbnail)) {
					errors.push(obj.name.first);
				} else {
					// Append it to the Map:
					savedData.set(obj.picture.thumbnail, obj);
				}
			});
			refreshDisplay();
			if (errors.length) {
				alert('The following were already selected:\n' + errors.join('\n'));
			}
		}

		function refreshDisplay() {
			$('.container').html('');
			savedData.forEach(function (obj) {
				// Reset container, and append collected data (use jQuery for appending)
				$('.container').append(
					$('<div>').addClass('parent').append(
						$('<label>').addClass('dataLabel').text('Name: '),
						obj.name.first + ' ' + obj.name.last,
						$('<br>'), // line-break between name & pic
						$('<img>').addClass('myLink').attr('src', obj.picture.thumbnail), $('<br>'),
						$('<label>').addClass('dataLabel').text('Date of birth: '),
						obj.dob, $('<br>'),
						$('<label>').addClass('dataLabel').text('Address: '), $('<br>'),
						obj.location.street, $('<br>'),
						obj.location.city + ' ' + obj.location.postcode, $('<br>'),
						obj.location.state, $('<br>'),
						$('<button>').addClass('removeMe').text('Delete'),
						$('<button>').addClass('top-btn').text('Swap with top'),
						$('<button>').addClass('down-btn').text('Swap with down')
					)	
				);
				resetEvents();
			})
			// Clear checkboxes:
			$('.selectRow').prop('checked', false);
		}

		function logSavedData(){
			// Translate Map to array of values:
			var data = Array.from(savedData, function (pair) {
				return pair[1];
			});
			// Convert to JSON and log to console. You would instead post it
			// to some URL, or save it to localStorage.
			console.log(JSON.stringify(data, null, 2));
		}

		$(document).on('click', '.removeMe', function() {
			var key = $('.myLink', $(this).parent()).attr('src');
			// Delete this from the saved Data
			savedData.delete(key);
			// And redisplay
			refreshDisplay();
		});
		
			/* Swapping the displayed articles in the result list */
			function resetEvents() {

				$(".top-btn, .down-btn").unbind('click');

				handleEvents();
				
				$('.down-btn').click(function() {
					var toMove1 = $(this).parents('.parent');

					$(toMove1).insertAfter($(toMove1).next());

					handleEvents();
				});

				$('.top-btn').click(function() {
					var toMove1 = $(this).parents('.parent');
					
					$(toMove1).insertBefore($(toMove1).prev());
					handleEvents();
				});

			}
				
			/* Disable top & down buttons for the first and the last article respectively in the result list */
			function handleEvents() {
				$(".top-btn, .down-btn").prop("disabled", false).show();

				$(".parent:first").find(".top-btn").prop("disabled", true).hide();

				$(".parent:last").find(".down-btn").prop("disabled", true).hide();
			}
			
			$(document).ready(function(){
				$('#showExtForm-btn').click(function(){
					$('#extUser').toggle();
				});
				$("#extArticleForm").submit(function(){

                    addExtUser();
                    return false;
               });
			});
			
			function addExtUser() {
				var name= $("#name").val();
				var imgsrc = $("#myImg").val();
				var dob = $("#dob").val();
				
				var errors = [];
                extObj = {};
				extObj = {};
				extObj["name"]["title"] = "mr";
				extObj["name"]["first"] = name;
				extObj["dob"] = dob;
				extObj["picture"]["thumbnail"] = imgsrc;
				savedData.push(extObj);
				if (savedData.get(imgsrc)) {
						errors.push(title);
					} else {
				$('.container').append(
					$('<div>').addClass('parent').append(
						$('<label>').addClass('dataLabel').text('Name: '),
						+name+
						$('<br>'), // line-break between name & pic
						$('<img>').addClass('myLink').attr('src', imgsrc), $('<br>'),
						$('<label>').addClass('dataLabel').text('Date of birth: '),
						+dob+ $('<br>'),
						$('<label>').addClass('dataLabel').text('Address: '), $('<br>'),
						+address+ $('<br>'),
						$('<button>').addClass('removeMe').text('Delete'),
						$('<button>').addClass('top-btn').text('Swap with top'),
						$('<button>').addClass('down-btn').text('Swap with down')
					)	
				);
				resetEvents();
				
			}
&#13;
table, th, td {
			border: 1px solid #ddd;
			border-collapse: collapse;
			padding: 10px;
		}

		.parent {
			height: 25%;
			width: 90%;
			padding: 1%;
			margin-left: 1%;
			margin-top: 1%;
			border: 1px solid black;

		}

		.parent:nth-child(odd){
			background: skyblue;
		}

		.parent:nth-child(even){
			background: green;
		}
		
		label {
			float: left;
			width: 80px;
		}
		input, textarea {
			width: 130px;
		}
		
		#extUser {
			border: 1px solid lightgrey;
			border-radius: 5px;
			display: none;
			padding: 10px;
			background-color: skyblue;
		}
		
		#extUserForm {
			margin: 3px;
			padding: 5px;
		}
&#13;
<button onclick="createTable()">Create Table</button>
		<table id="datatable">
			<tr><th>Select</th><th>Name</th><th>DOB</th></tr>
		</table>
		<button onclick="saveData()">Save Selected</button>
		<br />
		<div class="container"></div>
		<button onclick="logSavedData()">Get Saved Data</button>
		<button id="showExtForm-btn">Open External Form</button>
		
		<div id="extUser">
			<form id="extUserForm">
				<p>
					<label for="name">Name:</label>
					<input type="text" id="name" required>
				</p>
				<br />
				<p>
					<label for="myImg">Image:</label>
					<input type="url" id="myImg" required>
				</p>
				<br />
				<p>
					<label for="dob">DOB:</label>
					<input type="date" id="dob" required>
				</p>
				<br />
				<button onclick="addExtUser()">Submit</button>
			</form>
		</div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

表单提交存在问题:

  • 您在提交按钮上有onclick="addExtUser()",但是虽然您在该函数中返回false,但会忽略此返回值。应该是onclick="return addExtUser()"

  • 表单提交事件的监听器也调用了 addExtUser 。但是,表单的 id 拼写错误:它应该是$("#extUserForm").submit而不是$("#extArticleForm").submit

  • 但您只需要一种方法来调用 addExtUser ,因此请删除上述方法之一。我会建议第二种方式(纠正拼写)。

您可能希望首先隐藏表单,因此请将style="display:none"添加到HTML。

有一些代码重复,因为 addExtUser 有很多与 refreshDisplay 相同的代码:添加后应该调用 refreshDisplay 数据到 savedData

请注意,savedData.push不是Map上的有效方法,但我建议使用普通数组(请参阅有关交换记录的其他问题)。

定义对象的方式与JSON语法非常相似。这不起作用:

extObj = {};
extObj["name"]["title"] = "mr";

但这会:

var extObj = {
    name: {
        title: "mr", // No ladies? :-)
        first: $("#name").val(),
        // Last name ?
    },
    dob: $("#dob").val(),
    picture: {
        thumbnail: $("#myImg").val()
    },
    location: { // maybe also ask for this info?
    }
};

这是一个实现所有这一切的片段:

&#13;
&#13;
function createTable() {
    $.getJSON("https://api.randomuser.me/?results=5", function(data) {
        $('#datatable tr:has(td)').remove();
        data.results.forEach(function (record) {
            var json = JSON.stringify(record);
            $('#datatable').append(
                $('<tr>').append(
                    $('<td>').append(
                        $('<input>').attr('type', 'checkbox')
                                    .addClass('selectRow')
                                    .val(json)
                    ),
                    $('<td>').append(
                        $('<a>').attr('href', record.picture.thumbnail)
                                .addClass('imgurl')
                                .attr('target', '_blank')
                                .text(record.name.first)
                    ),
                    $('<td>').append(record.dob)
                )
            );
        })
    }).fail(function(error) {
        console.log("**********AJAX ERROR: " + error);
    });            
}

var savedData = []; // The objects as array, so to have an order.

function saveData(){
    var errors = [];
    // Add selected to map
    $('input.selectRow:checked').each(function(count) {
        // Get the JSON that is stored as value for the checkbox
        var obj = JSON.parse($(this).val());
        // See if this URL was already collected (that's easy with Set)
        if (savedData.find(record => record.picture.thumbnail === obj.picture.thumbnail)) {
            errors.push(obj.name.first);
        } else {
            // Append it
            savedData.push(obj);
        }
    });
    refreshDisplay();
    if (errors.length) {
        alert('The following were already selected:\n' + errors.join('\n'));
    }
}

function refreshDisplay() {
    $('.container').html('');
    savedData.forEach(function (obj) {
        // Reset container, and append collected data (use jQuery for appending)
        $('.container').append(
            $('<div>').addClass('parent').append(
                $('<label>').addClass('dataLabel').text('Name: '),
                obj.name.first + ' ' + obj.name.last,
                $('<br>'), // line-break between name & pic
                $('<img>').addClass('myLink').attr('src', obj.picture.thumbnail), $('<br>'),
                $('<label>').addClass('dataLabel').text('Date of birth: '),
                obj.dob, $('<br>'),
                $('<label>').addClass('dataLabel').text('Address: '), $('<br>'),
                obj.location.street, $('<br>'),
                obj.location.city + ' ' + obj.location.postcode, $('<br>'),
                obj.location.state, $('<br>'),
                $('<button>').addClass('removeMe').text('Delete'),
                $('<button>').addClass('top-btn').text('Swap with top'),
                $('<button>').addClass('down-btn').text('Swap with down')
            )	
        );
    })
    // Clear checkboxes:
    $('.selectRow').prop('checked', false);
    handleEvents();
}

function logSavedData(){
    // Convert to JSON and log to console. You would instead post it
    // to some URL, or save it to localStorage.
    console.log(JSON.stringify(savedData, null, 2));
}

function getIndex(elem) {
    return $(elem).parent('.parent').index();
}

$(document).on('click', '.removeMe', function() {
    // Delete this from the saved Data
    savedData.splice(getIndex(this), 1);
    // And redisplay
    refreshDisplay();
});

/* Swapping the displayed articles in the result list */
$(document).on('click', ".down-btn", function() {
    var index = getIndex(this);
    // Swap in memory
    savedData.splice(index, 2, savedData[index+1], savedData[index]);
    // And redisplay
    refreshDisplay();
});

$(document).on('click', ".top-btn", function() {
    var index = getIndex(this);
    // Swap in memory
    savedData.splice(index-1, 2, savedData[index], savedData[index-1]);
    // And redisplay
    refreshDisplay();
});
    
/* Disable top & down buttons for the first and the last article respectively in the result list */
function handleEvents() {
    $(".top-btn, .down-btn").prop("disabled", false).show();
    $(".parent:first").find(".top-btn").prop("disabled", true).hide();
    $(".parent:last").find(".down-btn").prop("disabled", true).hide();
}

$(document).ready(function(){
    $('#showExtForm-btn').click(function(){
        $('#extUser').toggle();
    });
    $("#extUserForm").submit(function(e){
        addExtUser();
        return false;
   });
});

function addExtUser() {
    var extObj = {
        name: {
            title: "mr", // No ladies? :-)
            first: $("#name").val(),
            // Last name ?
        },
        dob: $("#dob").val(),
        picture: {
            thumbnail: $("#myImg").val()
        },
        location: { // maybe also ask for this info?
        }
    };
    savedData.push(extObj);
    refreshDisplay(); // Will show some undefined stuff (location...)
}
&#13;
table, th, td {
    border: 1px solid #ddd;
    border-collapse: collapse;
    padding: 10px;
}

.parent {
    height: 25%;
    width: 90%;
    padding: 1%;
    margin-left: 1%;
    margin-top: 1%;
    border: 1px solid black;

}

.parent:nth-child(odd){
    background: skyblue;
}

.parent:nth-child(even){
    background: green;
}

label {
    float: left;
    width: 80px;
}
input {
    width: 130px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="createTable()">Create Table</button>
<table id="datatable">
    <tr><th>Select</th><th>Name</th><th>DOB</th></tr>
</table>
<button onclick="saveData()">Save Selected</button>
<br />
<div class="container"></div>
<button onclick="logSavedData()">Get Saved Data</button>
<button id="showExtForm-btn">Open External Form</button>

<div id="extUser" style="display:none">
    <form id="extUserForm">
        <p>
            <label for="name">Name:</label>
            <input type="text" id="name" required>
        </p>
        <br />
        <p>
            <label for="myImg">Image:</label>
            <input type="url" id="myImg" required>
        </p>
        <br />
        <p>
            <label for="dob">DOB:</label>
            <input type="date" id="dob" required>
        </p>
        <br />
        <button>Submit</button>
    </form>
</div>
&#13;
&#13;
&#13;