Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can "New Post" create more than just the title? #456

Open
AlchemyCompSol opened this issue Sep 9, 2014 · 11 comments
Open

Can "New Post" create more than just the title? #456

AlchemyCompSol opened this issue Sep 9, 2014 · 11 comments

Comments

@AlchemyCompSol
Copy link

When someone creates a connection, and they click on "New Post", all they can do is create a post title. How can I let them create the post content as well?

@AlchemyCompSol
Copy link
Author

I've been working on figuring this out, and I've gotten closer, but it's somewhat beyond my JS skills, so I'm going to need some help.

To give you a little more detail: when someone clicks on "New Post", there is just a field for title. I need to add a field for "post content" and "category."

Here's what I've figured out:

  • The template to create a new post is in admin/templates/tab-create-post.html I can edit the HTML and add new fields.
  • The function that creates a new post is function ajax_create_post() in admin/box.php. I can add parameters to the $args array in that function to add the content and category to the post.
  • box.js gets the information entered into that form into the ajax_create_post() function, and that's where I'm lost. I think the magic happens around line 48, but I'm not sure how to actually make it happen. Can someone give me some pointers?

@scribu
Copy link
Owner

scribu commented Sep 24, 2014

In box.js, look for where the createItemAndConnect method is called. It currently only accepts a title.

@AlchemyCompSol
Copy link
Author

Thanks!

Yes, I found the createItemAndConnect method. I tried adding another parameter like this:

createItemAndConnect: function(title) {
  var data, _this = this;
  data = {
    subaction: 'create_post',
    post_title: title,
    post_content: content,
  };
  return this.ajax_request(data, function(response) {
    _this.trigger('create', response);
  });
},

That generates a whole bunch of weird empty JS errors and breaks a whole bunch of things and doesn't work at all. If I do this:

createItemAndConnect: function(title) {
  var data, _this = this;
  data = {
    subaction: 'create_post',
    post_title: title,
  };
  return this.ajax_request(data, function(response) {
    _this.trigger('create', response);
  });
},

createItemAndConnect: function(content) {
  var data, _this = this;
  data = {
    subaction: 'create_post',
    post_content: content,
  };
  return this.ajax_request(data, function(response) {
    _this.trigger('create', response);
  });
},

Then obviously the second method overwrites the first.... the good news is that the second method does correctly save the post content, so that's a step in the right direction. But how would I modify this (and the CreatePostView method) so that it saves both the title and the content?

Thanks! I really appreciate your help!

@scribu
Copy link
Owner

scribu commented Sep 25, 2014

You're going to have to learn the basics of JavaScript and jQuery to pull this off. Plenty of good, free tutorials online. Good luck!

@scribu
Copy link
Owner

scribu commented Sep 25, 2014

Basically, the first attempt, where you got empty errors, was the right path. You just need to learn how to populate the content variable from the DOM.

@AlchemyCompSol
Copy link
Author

Thanks!

@ihorvorotnov
Copy link

@AlchemyCompSol in your first attempt you added content variable inside the function but it's undefined. You don't fill it with any content inside that function nor passing the value to the function.
Try this:

createItemAndConnect: function(title, content) {
  var data, _this = this;
  data = {
    subaction: 'create_post',
    post_title: title,
    post_content: content,
  };
  return this.ajax_request(data, function(response) {
    _this.trigger('create', response);
  });
},

Note the second argument for the createItemAndConnect function. And of course, as @scribu pointed out, you need to get your content from a DOM element (probably by an id of textarea you've just added to tab-create-post.html) into this variable before calling the function.

Right now it's just a logical assumption. You can try it, it should work. In a day or two I'll be doing this exact feature in a project Im working on, will share the results when I'm done.

@AlchemyCompSol
Copy link
Author

Thanks @ihorvorotnov !

Actually, I spent yesterday working with someone to figure this out. Here's what we came up with:

In box.js:

    createItemAndConnect: function(title, content, date, category) {
      var data, _this = this;
      data = {
        subaction: 'create_post',
        post_title: title,
        post_content: content,
        post_date: date,
        post_category: category
      };
      return this.ajax_request(data, function(response) {
        _this.trigger('create', response);
      });
    },

  CreatePostView = Backbone.View.extend({
    events: {
      'click button': 'createItem',
      'keypress :text': 'handleReturn'
    },
    initialize: function(options) {
      this.options = options;
      this.createButton = this.$('button');
      this.createInput = this.$(':text');

      //this.createInput = this.$(':text');

      this.createTitle = this.$('.post-title-input');
      this.createContent = this.$('.post-content-input');
      this.createDate = this.$('.post-date-input');
      this.createCategory = this.$('.post-category-input');
    },
    handleReturn: function(ev) {
      if (ev.keyCode === ENTER_KEY) {
        this.createButton.click();
        ev.preventDefault();
      }
    },
    createItem: function(ev) {
      var req, title, _this = this;
      ev.preventDefault();
      if (this.createButton.hasClass('inactive')) {
        return false;
      }

      //title = this.createInput.val();

      title = this.createTitle.val();
      content = this.createContent.val();
      date = this.createDate.val();
      category = this.createCategory.val();

      if (title === '') {
        this.createInput.focus();
        return;
      }
      this.createButton.addClass('inactive');
      req = this.collection.createItemAndConnect(title, content, date, category);
      req.done(function() {
        // _this.createInput.val('');
        _this.createTitle.val('');
        _this.createContent.val('');
        _this.createDate.val('');
        _this.createButton.removeClass('inactive');
      });
    }
  });


In box.php:

public function ajax_create_post() {
    if ( !$this->can_create_post() )
        die( -1 );

    $args = array(
        'post_title' => $_POST['post_title'],
        'post_author' => get_current_user_id(),
        'post_type' => $this->ctype->get( 'opposite', 'side' )->first_post_type(),
        'post_date' => $_POST['post_date'],
        'post_content' => $_POST['post_content'],
    );

    $from = absint( $_POST['from'] );

    $args = apply_filters( 'p2p_new_post_args', $args, $this->ctype, $from );

    $this->safe_connect( wp_insert_post( $args ) );
}

private function safe_connect( $to ) {
    $from = absint( $_POST['from'] );
    $to = absint( $to );

    if ( !$from || !$to )
        die(-1);

    // set the activity category
    wp_set_post_terms($to, $_POST['post_category'], 'activity_category');

    $p2p_id = $this->ctype->connect( $from, $to );

    self::maybe_send_error( $p2p_id );

    $item = $this->ctype->get( 'opposite','side')->item_recognize( $to );

    $out = array(
        'row' => $this->connection_row( $p2p_id, $item, true )
    );

    die( json_encode( $out ) );
}

protected function get_list_of_categories() {
    $args = array(
        'orderby'           => 'name',
        'order'             => 'ASC',
        'hide_empty'        => false,
    );
    return get_terms('activity_category', $args);
}


In tab-create-posts.html

<div id="create-activity">
<label>Title</label>
<input type="text" name="p2p_new_title" class="post-title-input" autocomplete="off" placeholder="Activity Title"/>
<label>Date</label>
<span>Be sure to use the format yyyy-mm-dd.  Example: 2014-09-29</span>
<input type="text" name="p2p_new_date" class="post-date-input" autocomplete="off" placeholder="yyyy-mm-dd"/>
<label>Description</label>
<textarea name="p2p_new_content" class="post-content-input" placeholder="Activity Description"></textarea>

<label>Category</label>
<select name="p2p_new_categories" class="post-category-input">
  <option value="">Choose a Category</option>
  {{# categories }}
  <option value="{{ term_id }}">{{ name }}</option>
  {{/ categories }}
</select>

<button class="button">{{{title}}}</button>
</div>

I hope that helps!

@ihorvorotnov
Copy link

Wow, you just saved me a bunch of time, thank you! :) I haven't even looked into that backbone part yet.

@AlchemyCompSol
Copy link
Author

Glad to help! I'm pretty sure I included everything, but if you want to see my full code, it's on Bitbucket - https://bitbucket.org/wpalchemist/chamber-dashboard-crm

@ihorvorotnov
Copy link

Thanks a lot! Will check it when I'm on this task.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants