【问题标题】:Add unlimited Text input DatePickers to fields added after the DOM is loaded using jQuery?添加无限文本输入 DatePickers 到使用 jQuery 加载 DOM 后添加的字段?
【发布时间】:2015-05-31 09:30:19
【问题描述】:

我有一个项目应用程序,可以将任意数量的“任务”记录加载到页面中。它使用 JavaScript 构建任务记录 HTML,然后在页面加载后将任务添加到 DOM。

我需要将日期选择器库附加到每个任务记录的某些日期字段。

我几乎可以使用任何库,但我在这里尝试使用这个轻量级的库https://github.com/camerond/jquery-minical

加载该库后,您通常可以执行以下操作将文本输入转换为日期选择器字段...在这里工作演示 http://codepen.io/jasondavis/pen/LEaVbE?editors=101

<input name="date_input" type="text">

// Code that is supposed to make a text filed into a Date-time selector/picker!
$(".date_input").minical({
    trigger: "a.calendar_icon"
});

现在我的演示应用程序被放置在这里解决这个问题...http://jsfiddle.net/jasondavis/pk109mkm/

为每个任务记录调用下面的这个函数,它会在 DOM 中创建一个任务条目......

// Add new Task Row HTML to the DOM
function add_task_row(taskRow){

    // Merge Function Parameters with Default Values
    taskRow = merge({
        taskid: '',
        projectid: '',
        name: '',
        description: '',
        status: '',
        priority: '',
        type: '',
        sort: '',
        heading: '',
        date_started: '',
        date_completed: '',
        date_due: '',
        milestone_id: '',
        assigned_user_id: '',
        targetElement: 'project_tasks',
    }, taskRow || {});  

    // var num is used to have a Number assigned to each Task Row.
    // 1st We get the value stored in #tasks_count
    var num = document.getElementById('tasks_count').value;

    // Create a DIV Node for our new Task Row and set the ID attribute value to 'task_'+num
    var newTaskRow = document.createElement('div');
    newTaskRow.setAttribute('id','task_'+num);  

    newTaskRow.innerHTML =  '<span class="handle" title="Drag and Drop to Reorder Tasks"></span>';


    // Add a Project Task Row
    newTaskRow.innerHTML +=  '<div class="task-name-wrap"><input class="name" name="name_'+num+'" id="name_'+num+'" placeholder="Name:" size=45 type="text" value="'+taskRow.name+'"></div>';
    newTaskRow.innerHTML += '<div class="task-status-wrap"><span class="selection-field-label">Status:</span><select name="status_'+num+'" id="status_'+num+'" class="status">'+buildFormSelection(statusArray, taskRow.status)+'</select></div>';
    newTaskRow.innerHTML += '<div class="task-priority-wrap"><span class="selection-field-label">Priority:</span><select name="priority_'+num+'" id="priority_'+num+'" class="priority">'+buildFormSelection(prioritiesArray, taskRow.priority)+'</select></div>';
    newTaskRow.innerHTML += '<div class="task-type-wrap"><span class="selection-field-label">Type:</span><select name="type_'+num+'" id="type_'+num+'" class="type">'+buildFormSelection(typesArray, taskRow.type)+'</select></div>';

    // milestone
    newTaskRow.innerHTML += '<div class="task-milestone-wrap"><span class="selection-field-label">Milestone:</span><select name="milestone_id_'+num+'" id="milestone_'+num+'" class="milestone">'+buildFormSelectionMultidimensionalArray(milestonesArray, taskRow.milestone_id)+'</select></div>';

    newTaskRow.innerHTML +=  '<input name="date_due_'+num+'" id="date_due_'+num+'" class="date_due" size=15 type="text" value="'+taskRow.date_due+'">';

    newTaskRow.innerHTML +=  '<input name="assigned_user_id_'+num+'" id="assigned_user_id_'+num+'" class="assigned_user_id" size=15 type="text" value="">';

    newTaskRow.innerHTML +=  '<input class="date_input" autocomplete="off" type="text" name="date_completed" id="date_completed" value="" title="" tabindex="0" size="11" maxlength="10"><a class="calendar_icon" href="#"></a>';


    newTaskRow.innerHTML += '<div class="task-tools-wrap"><a class="insert_task" data-parent-task-id="task_'+num+'"><span class="insert-arrow-icon"></span></a><a class="delete_task" onclick="remove_item_row('+num+')"><span class="trash-icon"></span> Delete</a></div>';

    newTaskRow.innerHTML += '<hr><br style="clear:both;">';

    var task = document.getElementById('project_tasks');
    task.appendChild(newTaskRow);

}

所以在我的任务记录添加到页面后,我需要以某种方式将一个工作日期选择器附加到每个 .date_input 输入字段! 任何帮助或想法如何做到这一点?

回顾一下,我需要能够在页面加载后向网页动态添加任意数量的文本输入字段,然后让这些输入字段与 JavaScript 日期时间选择器/选择器一起使用。

对于日期选择器来说,它几乎可以是任何库。我不确定如何使用它:
a) 无限输入字段。
b) 在 DOM 已经加载后添加的输入字段!

请帮忙!


更新问题

在此 JSFiddle 示例的第 486 行:http://jsfiddle.net/pk109mkm/7/ 是此代码为每个任务记录设置 DatePicker 库。它可以为我们分配给它的文件创建一个可用的日期选择器。但是由于某些未知原因,它不支持我尝试传递给它的任何特殊选项!

$(task).find(".date_input").minical({
    trigger: "a.calendar_icon"
});

为了演示,这里是一个新的 JSFiddle,其代码完全相同,只是我已将选项对象传递给 DatePicker 对象......http://jsfiddle.net/jasondavis/pk109mkm/10/

options 对象看起来像这样......

$(task).find(".date_input").minical({
  offset: {
    x: 100,
    y: 50
  },
  trigger: "a.calendar_icon",
  read_only: true,
  align_to_trigger: false,
  date_format: function(date) {
    return [date.getDate(), date.getMonth() + 1, date.getFullYear()].join("/");
  },
  appendCalendarTo: function() {
      return $('#project_tasks');
  },
  //initialize_with_date: true,
  show_clear_link: true,
});

如果您看到示例 JSFiddle,您会注意到这些选项都没有被使用!如果您查看浏览器控制台,您也会看到没有错误!

现在,如果您查看此演示 JSFiddle 示例 http://jsfiddle.net/jasondavis/2q2d6gza/,它不会在 DOM 加载后添加多个日期选择器......您将看到完全相同的代码和选项产生很大的不同,因为它们实际上会在这个演示!

【问题讨论】:

    标签: javascript jquery datepicker


    【解决方案1】:

    尝试添加

    $(task).find(".date_input").minical({
        trigger: "a.calendar_icon"
    });
    

    到你的函数结束。

    喜欢

    // Add new Task Row HTML to the DOM
    function add_task_row(taskRow){
    
        // Merge Function Parameters with Default Values
        taskRow = merge({
            taskid: '',
            projectid: '',
            name: '',
            description: '',
            status: '',
            priority: '',
            type: '',
            sort: '',
            heading: '',
            date_started: '',
            date_completed: '',
            date_due: '',
            milestone_id: '',
            assigned_user_id: '',
            targetElement: 'project_tasks',
        }, taskRow || {});  
    
        // var num is used to have a Number assigned to each Task Row.
        // 1st We get the value stored in #tasks_count
        var num = document.getElementById('tasks_count').value;
    
        // Create a DIV Node for our new Task Row and set the ID attribute value to 'task_'+num
        var newTaskRow = document.createElement('div');
        newTaskRow.setAttribute('id','task_'+num);  
    
        newTaskRow.innerHTML =  '<span class="handle" title="Drag and Drop to Reorder Tasks"></span>';
    
    
        // Add a Project Task Row
        newTaskRow.innerHTML +=  '<div class="task-name-wrap"><input class="name" name="name_'+num+'" id="name_'+num+'" placeholder="Name:" size=45 type="text" value="'+taskRow.name+'"></div>';
        newTaskRow.innerHTML += '<div class="task-status-wrap"><span class="selection-field-label">Status:</span><select name="status_'+num+'" id="status_'+num+'" class="status">'+buildFormSelection(statusArray, taskRow.status)+'</select></div>';
        newTaskRow.innerHTML += '<div class="task-priority-wrap"><span class="selection-field-label">Priority:</span><select name="priority_'+num+'" id="priority_'+num+'" class="priority">'+buildFormSelection(prioritiesArray, taskRow.priority)+'</select></div>';
        newTaskRow.innerHTML += '<div class="task-type-wrap"><span class="selection-field-label">Type:</span><select name="type_'+num+'" id="type_'+num+'" class="type">'+buildFormSelection(typesArray, taskRow.type)+'</select></div>';
    
        // milestone
        newTaskRow.innerHTML += '<div class="task-milestone-wrap"><span class="selection-field-label">Milestone:</span><select name="milestone_id_'+num+'" id="milestone_'+num+'" class="milestone">'+buildFormSelectionMultidimensionalArray(milestonesArray, taskRow.milestone_id)+'</select></div>';
    
        newTaskRow.innerHTML +=  '<input name="date_due_'+num+'" id="date_due_'+num+'" class="date_due" size=15 type="text" value="'+taskRow.date_due+'">';
    
        newTaskRow.innerHTML +=  '<input name="assigned_user_id_'+num+'" id="assigned_user_id_'+num+'" class="assigned_user_id" size=15 type="text" value="">';
    
        newTaskRow.innerHTML +=  '<input class="date_input" autocomplete="off" type="text" name="date_completed" id="date_completed" value="" title="" tabindex="0" size="11" maxlength="10"><a class="calendar_icon" href="#"></a>';
    
    
        newTaskRow.innerHTML += '<div class="task-tools-wrap"><a class="insert_task" data-parent-task-id="task_'+num+'"><span class="insert-arrow-icon"></span></a><a class="delete_task" onclick="remove_item_row('+num+')"><span class="trash-icon"></span> Delete</a></div>';
    
        newTaskRow.innerHTML += '<hr><br style="clear:both;">';
    
        var task = document.getElementById('project_tasks');
        task.appendChild(newTaskRow);
    
        $(newTaskRow).find(".date_input").minical({
            trigger: "a.calendar_icon"
        });
    
    }
    

    这是工作小提琴http://jsfiddle.net/pk109mkm/7/

    【讨论】:

    • 这并没有达到应有的效率。通过执行$(task).find(),您正在搜索列表中的所有任务,而不仅仅是您刚刚添加的新任务。您应该从task.appendChild() 捕获返回值并仅在其中搜索。
    • 是的,已经解决了。我会在 jQuery 中完成所有的 DOM 工作,让自己更整洁。
    • 感谢您的帮助,我总是乐于接受改进。总是喜欢学习更好的 JavaScript 技术,因为它是我最不为人知的语言,但我认为它是最有趣的语言之一!在这种情况下,我正在构建现有应用程序,因此我试图尽可能坚持使用一些现有代码。
    • @DGS 我早上会选择你的答案作为这个问题的答案。我已经用一个更新的问题修改了我的问题,我想问你是否有一个想法,因为你现在熟悉这个问题。如果没有,我会写一个新问题。基本上在您的示例中,我不能使用传递到库中的任何选项,因为它们被忽略了。当我创建一个新的 JSFiddle 时,它​​不会在页面加载后将字段添加到 DOM 中,然后我的自定义选项就起作用了。我只是想看看你是否知道这个问题是否有一个简单的解决方案?谢谢...看我的问题
    猜你喜欢
    • 1970-01-01
    • 2012-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-21
    相关资源
    最近更新 更多