如何在调用时让jQuery DatePicker不破坏<span>或<input />元素?

时间:2016-07-17 17:40:28

标签: javascript jquery wordpress datepicker

HTML中的某些内容或我使用jQuery Datepicker的方式会破坏此HTML中的目标元素editable-post-name-full。此HTML由WordPress生成;我无法建立一个模仿它的小提琴。

这是HTML;我想要定位的范围在单击“编辑”按钮之前称为#editable-post-name。

<span id="sample-permalink">
<a href="https://www.example.com/?p=1000" target='wp-preview-2198'>https://www.example.com/<span id="editable-post-name">test-post</span>/</a>
</span>

<span id="edit-slug-buttons">
<button type="button" class="edit-slug button button-small hide-if-no-js" aria-label="Edit permalink">Edit</button>
</span>
<span id="editable-post-name-full">test-post</span>

单击“编辑”按钮后,span标记将被破坏并在页面源中显示" autocomplete="off" />/。包含span标记的源代码如下所示:

page source

对于Datepicker,我正在使用

jQuery(document).ready(function() {
jQuery('#editable-post-name-full').each(function() {

jQuery(this).datepicker({

dateFormat: 'M-dd-yy',
showOn: "button",
                buttonImage: "../calendar.png",
                buttonImageOnly: true
           });

});
});

当我在jQuery函数中使用#new-post-slug时,DatePicker没有出现,我想是因为div #new-post-slug在点击Edit按钮之前不在HTML中。

只有在单击“编辑”按钮后才需要触发DatePicker吗?

所有jQuery库都是WordPress的最新版本,它们是jQuery UI 1.11.4,jQuery Datepicker 4.5.3,jQuerty 1.12.4。站点位于专用开发服务器上;网址不可用。

3 个答案:

答案 0 :(得分:1)

如果不是您想要的,请原谅。我想您希望能够激活日期选择器并使用结果来设置永久链接。我认为当你谈论破解时,它可能与日期选择器相关,期望输入而不是 span 来托管控件。

&#13;
&#13;
function getLink(postDate, postName){
  var _dateString = postDate.replace(/\//g,"")
  var _template = "https://www.example.com/{date}/{name}/";
  var _link = _template.replace("{date}", _dateString).replace("{name}", postName);
  return _link;
}

var inputName = document.getElementById("postName");
inputName.value = "test-post";

var inputDate = document.getElementById("datepicker");
inputDate.value = (new Date()).toLocaleDateString();

var inputLink = document.getElementById("permalink");
inputLink.value = getLink(inputDate.value, inputName.value);

$(inputDate).on("change", function(){
  inputLink.value = getLink(inputDate.value, inputName.value);
});

$(inputName).on("change", function(){
  inputLink.value = getLink(inputDate.value, inputName.value);
});

$(inputDate).datepicker({
  showOn: "button",
  buttonImage: "https://jqueryui.com/resources/demos/datepicker/images/calendar.gif",
  buttonImageOnly: true,
  buttonText: "Select date"
});
&#13;
input { width: 100%; }
&#13;
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.css" />

<table style="width: 100%;">
  <tr>
    <td style="width: 100px;">Post Name:</td>
    <td><input id="postName" type="text" value="test-post"/></td>
  </tr>
  <tr>
    <td>Post Date:</td>
    <td><input id="datepicker" type="text" style="display:none;" /></td>
  </tr>
  <tr>
    <td>Permalink:</td>
    <td><input id="permalink" type="text" readonly="readonly" disabled="disabled" /></td>
  </tr>
</table>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

首先,更改对象的ID是一个非常糟糕的主意(这会颠覆“标识符”一词的含义,并且非常容易出错)。

除此之外,我建议您只需添加类似“可编辑”的类,以区分可编辑对象和不可编辑对象。

话虽如此,下面的代码将无法正常工作(请参阅我为您添加的评论):

jQuery(document).ready(function() {
    // Executed once on Document Ready event (Ok).
    jQuery('#editable-post-name-full').each(function() {
        // Executed over each (pointed by this) element whose id
        // is "editable-post-name-full" JUST NOW (not in the future).
        ...
    });
});

...所以无论何时你改变那个对象id AFTER 文件就绪事件,下面.each()回调'#editable-post-name-full'选择器,但没有选择任何东西。

如果您想在触发某个事件时更改任何内容,那么您应该依赖该事件,而不是依赖于此事件处理程序添加的类或ID。

并且,如果您想稍后撤消,则需要手动撤消正确的事件,或者,只需使用两个不同的布局并交替显示/隐藏它们。

例如:

<span id="myDisplay" class="view">
   (Some date)
</span>
<span class="edit" style="display:none">
    <input class="datePicker" name="myDate" type="text">
</span>
<br />
<button id="myButton">Toggle Edit</button>
<script>
    $(function(){ // Not actually needed if code is at bottom of the document.
                    $(".datePicker").datepicker().on("change", function(){
                    $("#myDisplay").text($(this).val());
            });
            $("#myButton").on("click", function(){
                    $(".view,.edit").toggle();
            });
    });

JSfiddle)     

答案 2 :(得分:1)

回答我自己的问题:

这比我原先想象的要简单,并取决于我认为可能是关键:在包含div可见之后需要调用Datepicker。因此,我需要使用.on()来检测HTML中#new-post-slug何时可见。 (这是@bitifet的回答,但我不需要添加元素或切换元素;它们已经在HTML中)。而且,我正在尝试将Datepicker添加到input,而不是span,这是我错误的开始。

此解决方案还将Datepicker链接和calendar.png放在永久链接字段旁边,并且不依赖于#new-post-slug输入中的单击来显示它。这很有帮助,因为它可以让用户选择是否使用Datepicker作为slug或使用其他文本。

jQuery(document).ready(function() {

jQuery(document).on('click',"button.edit-slug.button.button-small.hide-if-no-js", function(){

  jQuery("input#new-post-slug").datepicker({
        showOn: 'button',
        buttonImageOnly: true,
        buttonImage: '../path-to-image/calendar.png', 
        dateFormat: 'M-dd-yy',
  })
});

});

补充说明:

为了在Post编辑器中使用Datepicker,您还必须在admin for Posts中加载上面的脚本(称为call-datepicker.js below)。 (这不包括在我的原始问题中,因为它是一种不必要的并发症)。这在你的主题functions.php文件中有用:

//Add Date Picker to Posts Editor

function add_admin_scripts( $hook ) {

    global $post;

    if ( $hook == 'post-new.php' || $hook == 'post.php' ) {
        if ( 'post' === $post->post_type ) {     
            wp_enqueue_script(  'myscript', get_stylesheet_directory_uri().'/call-datepicker.js' );
        }
    }
}
add_action( 'admin_enqueue_scripts', 'add_admin_scripts', 10, 1 );

删除对post.phpglobal $post;的挂钩调用,以便在页面上启用Datepicker。

另外还有一个关于WordPress用户的说明。我使用的WordPress主题没有在管理员中排队jQuery Datepicker,所以我需要这样做。这会加载WordPress自己的Datepicker副本;您可能还需要在主题文件夹中datepicker.css添加自己的CSS:

// Load Datepicker jQuery and CSS

function enqueue_datepicker_script() {

        wp_enqueue_script( 'jquery-ui-datepicker' );
        wp_register_style( 'datepicker_admin_css', get_template_directory_uri() . '/datepicker.css', false, '1.0.0' );
        wp_enqueue_style( 'datepicker_admin_css' );

}
add_action( 'admin_enqueue_scripts', 'enqueue_datepicker_script' );