রেলস 3: "ক্ষেত্র-ত্রুটিযুক্ত" র‍্যাপার পৃষ্ঠার উপস্থিতি পরিবর্তন করে। কীভাবে এড়ানো যায়?


131

ইমেল ক্ষেত্র:

<label for="job_client_email">Email: </label> 
<input type="email" name="job[client_email]" id="job_client_email">

এটা এমন দেখতে:

নির্ভুল

তবে, যদি ইমেলের বৈধতা ব্যর্থ হয় তবে তা হয়ে যায়:

<div class="field_with_errors">
  <label for="job_client_email">Email: </label>
</div> 
<div class="field_with_errors">
  <input type="email" value="wrong email" name="job[client_email]" id="job_client_email">
</div>

যা দেখতে এরকম দেখাচ্ছে:

with_error

আমি কীভাবে এই চেহারা পরিবর্তন এড়াতে পারি?


হাই @ মিসহা-মোরোস্কো, আমি এখানে বর্ণিত হিসাবে পিতামাতার স্তরে ত্রুটি শ্রেণি যুক্ত করার চেষ্টা করব । আমি বাইবেগ ব্যবহার করে রেল কোডে ডুব দেওয়ার চেষ্টা করেছি তবে আমি তাত্ক্ষণিকভাবেই হারিয়ে গেলাম those এই ক্ষেত্রটির কোনও পিতা বা মাতা আছে কিনা তা খতিয়ে দেখে আমি এই আচরণটি সামান্য স্মার্ট পদ্ধতিতে সেটআপ করতে চেয়েছিলাম ..
সানজিবুকাই

উত্তর:


235

আপনি ওভাররাইড করা উচিত ActionView::Base.field_error_proc। এটি বর্তমানে এটির মধ্যে এটি হিসাবে সংজ্ঞায়িত ActionView::Base:

 @@field_error_proc = Proc.new{ |html_tag, instance| 
   "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe
 }

আপনি আপনার অ্যাপ্লিকেশনটির ক্লাসের ভিতরে এটি রেখে ওভাররাইড করতে পারেন config/application.rb:

config.action_view.field_error_proc = Proc.new { |html_tag, instance| 
  html_tag
}

এই পরিবর্তনটি কার্যকর হওয়ার জন্য রেল সার্ভার পুনরায় চালু করুন।


4
একটি ছোট্ট প্রশ্ন: কেন labelএবং উভয়ই inputমোড়ানো? কীভাবে র‌্যালগুলি সিদ্ধান্ত নেবে যে কী জড়ান?
মিশা মোরোশকো

4
এটি সম্ভবত এটি করা হয়েছে যাতে আপনি কোনও ক্ষেত্রের লেবেলকে ত্রুটিযুক্ত করেও স্টাইল করতে পারেন। এছাড়াও, পাগল জানেন মোড়ানো কারণ আপনি এটি তা বলুন ক্ষেত্র রিসোর্সের কি অ্যাট্রিবিউট আপনার জন্য ফর্ম তৈরি করছেন অন্তর্গত: f.label :passwordএবং f.password_field :password@resource.errorsসেখানে হবে [:password]ত্রুটি সেট।
মোসেলম্যান

3
আপনি যদি টুইটার বুটস্ট্র্যাপের সাথে কাজ করছেন, বা আপনি ফিল্ড_অরর_প্রোকটিতে কী করতে পারেন তার অন্য একটি উদাহরণ চান, তবে এই দুর্দান্ত ঘটনাটি দেখুন
রায়ান

2
কেন কেউ "# {html_tag}" করেন? Html_safe, এবং html_tag.html_safe নয়?
অনুরাগ

3
অনুরাগ: যদি এইচটিএমএল_ট্যাগ শূন্য হয়, বা স্ট্রিং ব্যতীত অন্য কিছু হয়ে থাকে, তবে একটি সরল html_tag.html_safe একটি ত্রুটি তৈরি করবে। এটিকে "# {এইচটিএমএল_ট্যাগ}" এ প্রবিষ্টভাবে এইচটিএমএল_ট্যাগ.টো_এস কল করে, যা আশা করে একটি স্ট্রিং ফিরে আসবে, যা এইচটিএমএল_সেফ
সকমনক

100

আপনি যে ভিজ্যুয়াল পার্থক্যটি দেখছেন তা ঘটছে কারণ divউপাদানটি একটি ব্লক উপাদান। কোনও ইনলাইন উপাদানের মতো আচরণ করার জন্য এই স্টাইলটি আপনার সিএসএস ফাইলে যুক্ত করুন:

.field_with_errors { display: inline; }

2
এটি সর্বোত্তমভাবে একটি হ্যাক কারণ এটি উপরের যে কোনও display:সম্পত্তি (এবং অন্যান্য লেআউট শৈলী) ব্যবহৃত হচ্ছে তা উপেক্ষা করে html_tag
রায়ান

1
আমি এটিকে হ্যাক হিসাবে দেখছি না। displayএই সিএসএস যুক্ত হওয়ার আগে যে সম্পত্তি ব্যবহার করা হচ্ছে তা হ'ল blockযা চাক্ষুষ পার্থক্যটি ঘটাচ্ছে যা পছন্দসই নয়। এটি ট্যাগে অন্য কোনও লেআউট শৈলী অস্বীকার করে না। যাইহোক, আপনি যদি ট্যাগটি পরিবর্তন করে / ফিল্ডটিকে ত্রুটিযুক্তভাবে মোড়ানো করতে চান তবে রায়ান বিগের উত্তরটি সঠিক।
dontangg

আমি এটি চেষ্টা করেছিলাম, তবে, যদি আপনার ক্ষেত্রগুলি <p> ট্যাগগুলি ভিতরে থাকে তবে এটি কাজ করে না বলে মনে হচ্ছে (কমপক্ষে ফায়ারফক্সে নয়) যেহেতু <p> এর মধ্যে <p> লাইনে কিছু ভাঙ্গা যায় না। বিগস সমাধান ব্যবহার করে, কেবল <ডিভের সাথে <স্প্যান প্রতিস্থাপনের কৌশলটি মনে হচ্ছে।
jpw

72

আমি বর্তমানে এই সমাধানটি ব্যবহার করি, একটি প্রারম্ভকরে রাখা:

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  class_attr_index = html_tag.index 'class="'

  if class_attr_index
    html_tag.insert class_attr_index+7, 'error '
  else
    html_tag.insert html_tag.index('>'), ' class="error"'
  end
end

এটি আমাকে অতিরিক্ত উপাদান তৈরি না করে যথাযথ ট্যাগটিতে কেবল শ্রেণির নাম যুক্ত করতে দেয়।


2
একটি তাত্পর্যপূর্ণ ক্ষেত্রকে একটি নিরর্থক উপায়ে ব্যবহার করার জন্য এটি দুর্দান্ত।
রায়ান 21

1
রেলগুলিতে কাজ করে 4.0.০.৩।
ইউকি মাতসুকুরা

1
আমার জন্য কাজ করেছেন। পরিবর্তনগুলি লক্ষ্য করার জন্য রেল সার্ভার পুনরায় চালু করতে হয়েছিল :)
জেজেন টমাস

1
আমি এই সমাধানটি পছন্দ করেছিলাম, তবে যদি আপনার ভিতরে অন্য ট্যাগ থাকে তবে এটি কাজ করবে না label
Caio তারিফা

হাই @ ফোবেট্রন, সত্যিই এটি একটি দুর্দান্ত সমাধান। আমি এখানে বর্ণিত পরিবর্তে অভিভাবক স্তরে সেই শ্রেণিটি যুক্ত করার জন্য একটি উপায় অনুসন্ধান করি । আমি রেল কোডে ঘুঘু হয়েছি কিন্তু আমি তত্ক্ষণাত নিজেকে হারিয়ে ফেলেছি বাইবেগ দিয়ে রেন্ডারিং প্রক্রিয়াটি অনুসরণ করতে সক্ষম না হয়ে .. আপনি কি জিনিসটি বাস্তবে সম্ভব?
সানজিবুকাই

20

অতিরিক্ত কোড যুক্ত করা হচ্ছে ActionView::Base.field_error_proc। আপনি যদি field_with_errorsনিজের ফর্মটি স্টাইল করতে না ব্যবহার করেন তবে আপনি এটিকে ওভাররাইড করতে পারেন application.rb:

config.action_view.field_error_proc = Proc.new { |html_tag, instance| html_tag.html_safe }

বিকল্পভাবে, আপনি এটি এমন কিছুতে পরিবর্তন করতে পারেন যা আপনার ইউআইয়ের সাথে খাপ খায়:

config.action_view.field_error_proc = Proc.new { |html_tag, instance| "<span class='field_with_errors'>#{html_tag}</span>".html_safe }

এটি আমার পক্ষে ভাল কাজ করছে; টুইটার বুটস্ট্র্যাপের সাথে ব্যবহারের জন্য সর্বাধিক মার্জিত সমাধান বলে মনে হচ্ছে
এভিশাই

5

আমি রেল 5 এবং ম্যাটারিয়ালাইজ-সাসের সাথে কাজ করছি এবং নীচের চিত্রের মতো ব্যর্থ ক্ষেত্রের বৈধতাগুলি চিকিত্সার জন্য আমি রইলের কাছ থেকে ডিফল্ট আচরণ নিয়ে কিছু সমস্যা পাচ্ছি এবং এটি divইনপুট ক্ষেত্রগুলিতে অতিরিক্ত যুক্ত হওয়ার কারণে যেখানে বৈধতা ব্যর্থ হয়েছিল।

এখানে চিত্র বর্ণনা লিখুন

@ ফোবেট্রন উত্তর নিয়ে কাজ করা এবং হুগো ডেমিগ্লিয়োর উত্তরও সংশোধন করা। কোডগুলির সেই ব্লকগুলিতে আমি কিছু সামঞ্জস্য করেছি এবং নিম্নলিখিত ক্ষেত্রে আমি কিছু ভাল কাজ করছি:

  • উভয় inputএবং কোথাও labelতাদের নিজস্ব classবৈশিষ্ট্য আছে
    • <input type="my-field" class="control">
    • <label class="active" for="...">My field</label>
  • যদি inputবা labelট্যাগগুলির কোনও classবৈশিষ্ট্য না থাকে
    • <input type="my-field">
    • <label for="...">My field</label>
  • যদি labelট্যাগটির সাথে অন্য ট্যাগ থাকেclass attribute
    • <label for="..."><i class="icon-name"></i>My field</label>

এই সমস্ত ক্ষেত্রে errorক্লাসটি বিদ্যমান classথাকলে অ্যাট্রিবিউটে বিদ্যমান ক্লাসে যোগ করা হবে বা এটি লেবেল বা ইনপুট ট্যাগগুলিতে উপস্থিত না থাকলে এটি তৈরি করা হবে ।

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
    class_attr_index = html_tag.index('class="')
    first_tag_end_index = html_tag.index('>')

    # Just to inspect variables in the console
    puts '😎 ' * 50
    pp(html_tag)
    pp(class_attr_index)
    pp(first_tag_end_index)

    if class_attr_index.nil? || class_attr_index > first_tag_end_index
        html_tag.insert(first_tag_end_index, ' class="error"')
    else
        html_tag.insert(class_attr_index + 7, 'error ')
    end

    # Just to see resulting tag in the console
    pp(html_tag)
end

আমি আশা করি আমার মতো একই শর্তযুক্ত কারও পক্ষে এটি কার্যকর হতে পারে।


4

@ ফোবেট্রন উত্তর ছাড়াও, যখন আপনার ক্লাস অ্যাট্রিবিউটের মতো অন্য ট্যাগ থাকে তখন কাজ করে না <label for="..."><i class="icon my-icon"></i>My field</label>

আমি তার সমাধানটিতে কিছু পরিবর্তন করেছি:

# config/initializers/field_with_error.rb

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  class_attr_index = html_tag.index('class="')
  first_tag_end_index = html_tag.index('>')

  if class_attr_index.nil? || first_tag_end_index > class_attr_index
    html_tag.insert(class_attr_index + 7, 'error ')
  else
    html_tag.insert(first_tag_end_index, ' class="error"')
  end
end

আপনার ক্ষেত্রের ক্লাস বৈশিষ্ট্য না থাকলে তবে এটি কাজ করবে না
মিজুরানিক্স

2

যদি কোনও কারণে আপনি এখনও রেল 2 এ কাজ করছেন (যেমন আমি আছি) এসও পোস্টটি এখানে দেখুন

ইনিশিয়ালাইজারগুলিতে রাখার জন্য এটি স্ক্রিপ্ট সরবরাহ করে।


2

একটি বিষয় মনে রাখবেন (যেমন আমি আজ এটির মাধ্যমে কাজ করে দেখেছি) হ'ল আপনি যদি লেবেল বা ইনপুট ক্ষেত্রগুলিতে (আমি সমস্ত ইনপুট ক্ষেত্রগুলি ডানদিকে ভাসিয়ে দিই) ভাসিয়ে রাখি, আপনি অ্যাকশনভিউকে ওভাররাইড করলেও সিএসএস ভেঙে যাবে: Base.field_error_proc।

বিকল্পটি হ'ল সিএসএস ফর্ম্যাটিংয়ের মতো আরও গভীর স্তর ফেলে দেওয়া:

.field_with_errors label {
  padding: 2px;
  background-color: red;
}

.field_with_errors input[type="text"] {
  padding: 3px 2px;
  border: 2px solid red;
}

2

আমি কিছু বস্তুর জন্য এই ভয়ঙ্কর জিনিসটি অক্ষম করার জন্য একটি বিকল্প তৈরি করেছি

# config/initializers/field_error_proc.rb

module ActiveModel::Conversion
  attr_accessor :skip_field_error_wrapper
end

ActionView::Base.field_error_proc = Proc.new {|html_tag, instance|
  if instance.object && instance.object.skip_field_error_wrapper
    html_tag.html_safe
  else
    "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe
  end
}

সুতরাং এটি এটি ব্যবহার করতে পারেন:

@user.skip_field_error_wrapper = true
form_for(@user) do |f|
  ...
end

1

@ ফোবেট্রনের উত্তরের উপরে এটি আমার সমাধান বিল্ডিং। এই কোডটি স্থাপন করে application.rb, আপনার <p>এবং <span>সংশ্লিষ্ট form.error :pকলগুলির দ্বারা উত্পন্ন ট্যাগগুলি fields_with_errorsসিএসএস ট্যাগ পাবেন। বাকিরা errorসিএসএস ক্লাস পাবেন।

config.action_view.field_error_proc = Proc.new { |html_tag, instance|
  class_attr_index = html_tag.index 'class="'

  if class_attr_index
    # target only p's and span's with class error already there
    error_class = if html_tag =~ /^<(p|span).*error/
      'field_with_errors '
    else
      'error '
    end

    html_tag.insert class_attr_index + 7, error_class
  else
    html_tag.insert html_tag.index('>'), ' class="error"'
  end
}

আমার ফর্মগুলি জুড়ে প্রতিক্রিয়াটিকে স্টাইল করার জন্য আমি এইভাবে সর্বাধিক নমনীয় এবং নিরস্তর বলে মনে করেছি।


1

যদি এটি কেবল স্টাইলিংয়ের উদ্দেশ্যে হয় (আপনার কোনও আপত্তি নেই div) তবে আপনি এটি আপনার সিএসএসে যুক্ত করতে পারেন:

div.field_with_errors {
 display: inline;
}

divএকটি মত কাজ করবে spanএবং এটি আপনার নকশা সঙ্গে হস্তক্ষেপ করবে না (যেহেতু divএকটি ব্লক উপাদান - display: block;- ডিফল্ট দ্বারা, এটি একটি নতুন লাইন এটা বন্ধ পর করব | spanহয় inline, তাই এটি না)।


1

আপনি যদি কিছু নির্দিষ্ট উপাদানের উদাহরণস্বরূপ চেকবক্সগুলি বন্ধ করতে চান তবে আপনি এটি করতে পারেন:

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  doc = Nokogiri::HTML::Document.parse(html_tag)
  if doc.xpath("//*[@type='checkbox']").any?
    html_tag
  else
    "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe
  end
end

0

যদি এটি কেবল স্টাইলিং সম্পর্কিত সমস্যা থাকে তবে আমরা "ক্ষেত্র_দ্বীপ_পরিচয়" ওভাররাইট করতে পারি। তবে এটি আমাদের আবেদনে অন্যান্য ফর্মগুলিকে প্রভাবিত করতে পারে, কেবলমাত্র সেই ফর্মের সাথে "ফিল্ড_উইথ_অর্থগুলি" ক্লাসটি ওভাররাইট করা ভাল।

'প্যারেন্ট_ক্লাস' বিবেচনা করা ফর্মের ত্রুটি ক্ষেত্রের জন্য অন্যতম মূল বর্গ (ত্রুটি ক্ষেত্রের জন্য ফর্মের শ্রেণি বা প্যারেন্ট উপাদানগুলির কোনও শ্রেণি), তারপরে

  .parent_class .field_with_errors {
    display: inline;
  }

এটি সমস্যাটিও ঠিক করে দেবে, এটি আমাদের আবেদনকারীর অন্য কোনও ফর্মকেও বিরক্ত করবে না।

অথবা

যদি আমাদের পুরো আবেদনকারীর জন্য "ক্ষেত্র_দ্বীপ_পদ্ধতি" এর স্টাইলটি ওভাররাইড করা দরকার, তবে @ দন্তাং যেমন বলেছেন,

.field_with_errors { display: inline; } 

ঠিক করবে। আশা করি এটা সাহায্য করবে :)


0

আপনি যদি field_error_procআপনার পুরো অ্যাপ্লিকেশনটির জন্য পরিবর্তন করতে না চান , jQuery এর আন - র্যাপ নির্দিষ্ট সমস্যা ক্ষেত্রগুলির জন্য আরও লক্ষ্যযুক্ত সমাধান সরবরাহ করতে পারে, যেমন,

$('FORM .field_with_errors > INPUT[type="checkbox"]').unwrap();
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.