Tallboy
Tallboy

Reputation: 13417

Really having difficulty with New tokens on token input (from different model)

Im using jquery-tokeninput, but a fork of it which allows the User to add new custom tokens (Tag) for each Resource.

Example here (Scroll down to the tag box and type a few letters. you can type ones that dont exist): http://www.tomsguide.fr/solutions/nouveau_sujet.htm

The current return value from the fork I'm using is this (new value in quotes):

16,42,'Subway',37,'McDonald\'s',734

I'm having extreme difficulty trying to handle this in Rails. This sums it up perfectly.

This is what I have so far, and its not working, probably for a lot of reasons I'm not seeing, but the main reason is that I need to create new Tag instances but not save them, that way I can somehow pass them back into the token input, and save the new Tags along with the new Resource when they submit the form. When you use Tag.new though, it doesnt create an ID.

resource.rb

attr_accessor :tokens_list

# CUSTOM TOKENS                 
def tag_tokens=(tokens)
  self.tokens_list = tokens.split(",")

  if new_custom_tokens?
    self.tokens_list.each do |token|
      tokens_list << token if token.include? "'"
    end
  end

  self.tag_ids = self.tokens_list
end

def new_custom_tokens?
  self.tokens_list.each do |token|
    return true if token.include? "'"
  end
  false
end

resources_controller.rb

def create
  @title = "Submit Resource"
  @resource = Resource.new(params[:resource])

  assign_to_global_user?

  # CUSTOM TOKENS
  if @resource.new_custom_tokens?
    custom_token_time_restriction
    # Create Tag.new
  end

  if @resource.valid?
    @resource.save
    flash[:notice] = "Your link has been successfully submitted."
    redirect_to root_url
  else
    render :action => :new
  end 
end

def assign_to_global_user?
  if user_signed_in?
    @resource.user_id = current_user.id
  else
    @resource.user_id = User.find_by_username("Global_User").id
  end
end

private

# CUSTOM TOKENS   
def custom_token_time_restriction
  limit = 7 # days
  if (@resource.user_id != User.global_user_id) and (Time.now - limit.days > User.find(@resource.user_id).created_at)
    # TODO: Check if they are anonymous or their account is newer than 7 days
  else
    flash[:notice] = "You be Logged in to add new tags, and your account must be older than #{limit} days."
    render :action => :new
  end
end

new.html.erb (for resource#new)

<div class="field">
  <%= f.label :tags %>
  <%= f.text_field :tag_tokens, "data-pre" => @resource.tags.to_json(:only => [:id, :name]), :class => :tagbox %>
</div>

Upvotes: 0

Views: 696

Answers (1)

Kashyap
Kashyap

Reputation: 479

I had the same problem. This is what I have done:

This is the function where I return tokens of search in json format.

tags = TagMaster.where("name LIKE ?", "%#{params[:q]}%").limit(10)
if tags == []
  list << {"id" => "0","name"=>new_tag.rstrip}
else
  tags.each { |tag| list << {"id" => tag.id.to_s, "name" => tag.name }}
end

respond_to do |format|
  format.json { render :json => list.to_json, :layout => false }
end

Now this will allow show you whatever you type in auto complete dropdown and on clicked it will show as a token.

Now you can't add any more custom tokens because any token that is not in database will return id 0 so only one custom token is allowed at this point of time.

For that problem I did following.

var k = jQuery.noConflict();
k("#project_tags").tokenInput("tag_list", {
  hintText: "Enter Tags for your Project",
  noResultsText: "No Such Tags",
  searchingText: "Looking for your Tags",
  preventDuplicates: true,
  theme: "facebook",
  onAdd: function (item) {
    if (item.id == '0') {
      k.ajax({
    url: '/add_project_tag',
        data: { name: item.name },
    success:function(data) {
          k("#project_tags").tokenInput("add", {id: data, name: item.name});
          k("#project_tags").tokenInput("remove", {id: '0' });
        }
  });
    }
  }
});

As you can see here i call add_project_tag where I store that custom tag into database and it returns id of that inserted tag. So now you simply add the same token with it's id and remove token with 0.

So now there won't be any token with 0 and you can add as many new token as you want.

Hope this helps. Throw your questions if any more complications.

Upvotes: 1

Related Questions