এইচটিএমএল ফর্ম সম্পাদনা করা হয়েছে কিনা তা সনাক্ত করার জেনেরিক উপায়


94

আমার একটি ট্যাবড এইচটিএমএল ফর্ম রয়েছে। এক ট্যাব থেকে অন্য ট্যাবে নেভিগেট করার পরে, ডেটাতে কোনও পরিবর্তন না থাকলেও বর্তমান ট্যাবের ডেটা (ডিবিতে) বজায় থাকে।

আমি ফর্মটি সম্পাদিত হলেই দৃistence়তা কল করতে চাই। ফর্মটিতে যে কোনও ধরণের নিয়ন্ত্রণ থাকতে পারে। ফর্মটি খালি করা কিছু পাঠ্য টাইপ করার দরকার নেই তবে একটি ক্যালেন্ডার নিয়ন্ত্রণে একটি তারিখ চয়ন করাও যোগ্যতা অর্জন করবে।

এটি অর্জনের একটি উপায় হ'ল ডিফল্টরূপে কেবল পঠন মোডে ফর্মটি প্রদর্শন করা এবং একটি 'সম্পাদনা' বোতাম থাকা এবং ব্যবহারকারী যদি সম্পাদনা বোতামটি ক্লিক করেন তবে ডিবিতে কল করা হবে (আবারও, ডেটা সংশোধিত কিনা তা নির্বিশেষে) এটি বর্তমানে বিদ্যমান যা এটির উন্নততর উন্নতি)।

আমি জানতে চাই যে কীভাবে একটি জেনেরিক জাভাস্ক্রিপ্ট ফাংশন লিখতে হবে যা পরীক্ষা করে দেখবে যে নিয়ন্ত্রণের কোনও মান পরিবর্তন করা হয়েছে কিনা?


ক্রেইগ বকলার সাইট পয়েন্টে একটি আকর্ষণীয় সমাধান পোস্ট করেছেন। বিশেষ আগ্রহের বিষয় হল, সমাধানটি jQuery এর উপর নির্ভর করে না এবং এটি ক্রস ব্রাউজারের সাথে সামঞ্জস্যপূর্ণ।
ম্যাজিকঅ্যান্ডি

উত্তর:


159

খাঁটি জাভাস্ক্রিপ্টে, এটি কোনও সহজ কাজ হবে না, তবে jQuery এটিকে করা খুব সহজ করে তোলে:

$("#myform :input").change(function() {
   $("#myform").data("changed",true);
});

তারপরে সংরক্ষণের আগে, আপনি এটি পরীক্ষা করে দেখতে পারেন কিনা:

if ($("#myform").data("changed")) {
   // submit the form
}

উপরের উদাহরণে, ফর্মটির "মাইফর্ম" এর সমান একটি আইডি রয়েছে।

আপনার যদি বিভিন্ন আকারে এটির প্রয়োজন হয় তবে আপনি এটিকে সহজেই একটি প্লাগইনে রূপান্তর করতে পারেন:

$.fn.extend({
 trackChanges: function() {
   $(":input",this).change(function() {
      $(this.form).data("changed", true);
   });
 }
 ,
 isChanged: function() { 
   return this.data("changed"); 
 }
});

তারপরে আপনি সহজভাবে বলতে পারেন:

$("#myform").trackChanges();

এবং কোনও ফর্ম পরিবর্তিত হয়েছে কিনা তা পরীক্ষা করুন:

if ($("#myform").isChanged()) {
   // ...
}

13
এটি দুর্দান্ত এবং সাধারণ। তবে যদি কোনও ব্যবহারকারী কোনও ফর্ম ইনপুট পরিবর্তন করে এবং তারপরে পরিবর্তনটি (যেমন উদাহরণস্বরূপ দুবার একটি চেকবাক্স ক্লিক করে) পরিবর্তন করে, তবে ফর্মটি পরিবর্তিত হিসাবে বিবেচিত হবে। তা গ্রহণযোগ্য কিনা তা অবশ্যই প্রসঙ্গে নির্ভর করবে। বিকল্পের জন্য দেখুন স্ট্যাকওভারফ্লো.com
সেকশনস ১০৩১১663

4
লাইভ ইনপুটগুলির জন্য কিছু পরিবর্তন দরকার trackChanges: function () { $(document).on('change', $(this).find(':input'), function (e) { var el = $(e.target); $(el).closest('form').data("changed", true); });
ডিম্মডুহ

36

যদি জিকুয়েরি প্রশ্নের বাইরে থাকে। গুগলে একটি তাত্ক্ষণিক অনুসন্ধানে MD5 এবং SHA1 হ্যাশ অ্যালগরিদমের জাভাস্ক্রিপ্ট বাস্তবায়ন পাওয়া গেছে। আপনি যদি চান, আপনি সমস্ত ফর্ম ইনপুট একত্রিত করতে এবং সেগুলিতে হ্যাশ করতে পারেন, তারপরে সেই মানটি মেমোরিতে সঞ্চয় করুন। যখন ব্যবহারকারী সম্পন্ন হয়। সমস্ত মান এবং হ্যাশ আবার জড়ান। 2 টি হ্যাশ তুলনা করুন। যদি সেগুলি একই হয় তবে ব্যবহারকারী কোনও ফর্ম ক্ষেত্র পরিবর্তন করেনি। যদি সেগুলি আলাদা হয় তবে কিছু সম্পাদনা করা হয়েছে এবং আপনাকে আপনার অধ্যবসায়ের কোডটি কল করতে হবে।


4
এই প্রশ্নটির জন্য আমি এটিই প্রত্যাশা করেছিলাম, কোনও লাইব্রেরি আছে কি?
হামেদজ

আপনি যদি সমস্ত ক্ষেত্রকে একত্রিত করে তা হ্যাশ না করেন তবে কি একই ফলাফল হবে না ?
ashaleedawg

হ্যাঁ, তবে ডেটা নিজেই হ্যাশের চেয়ে বড় হতে পারে।
জেআরজি

26

আমি আপনার প্রশ্নটি সঠিকভাবে পেয়েছি কিনা তা সম্পর্কে আমি নিশ্চিত নই, তবে অ্যাডএভেন্টলিস্টনার কী? আপনি যদি IE8 সমর্থন সম্পর্কে খুব বেশি যত্ন না রাখেন তবে এটি ঠিক করা উচিত। নিম্নলিখিত কোডটি আমার জন্য কাজ করছে:

var form = document.getElementById("myForm");

form.addEventListener("input", function () {
    console.log("Form has changed!");
});

আমার প্রয়োজনের জন্য নিখুঁত
আশীর্বাদ

8

এটি অর্জনের আর একটি উপায় হ'ল ফর্মটি সিরিয়ালাইজ করা:

$(function() {
    var $form = $('form');
    var initialState = $form.serialize();
    
    $form.submit(function (e) {
      if (initialState === $form.serialize()) {
        console.log('Form is unchanged!');
      } else {
        console.log('Form has changed!');
      }
      e.preventDefault();
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
Field 1: <input type="text" name="field_1" value="My value 1"> <br>
Field 2: <input type="text" name="field_2" value="My value 2"> <br>
Check: <input type="checkbox" name="field_3" value="1"><br>
<input type="submit">
</form>


আপনি কীভাবে ভাবছেন তা আমি পছন্দ করি, বিশেষত যদি আপনি jQuery ছিঁড়ে ফেলেন এবং ভ্যানিলা জাভাস্ক্রিপ্ট দিয়ে এটি করেন। আমি বুঝতে পারলাম যে প্রশ্নটি অনুমান করা হয়েছে jQuery উপলব্ধ ছিল, তবে মন্তব্যগুলিতে সতর্কতার সাথে এর অনুরূপ আরও ব্যাপকভাবে প্রয়োগযোগ্য সমাধান না পাওয়ার কোনও কারণ নেই ।
ruffin

4

আমি এখানে এটি কীভাবে করেছি (jQuery ব্যবহার না করে)।

আমার ক্ষেত্রে, আমি চেয়েছিলাম একটি নির্দিষ্ট ফর্ম উপাদান গণনা করা উচিত নয়, কারণ এটি উপাদান যা চেককে ট্রিগার করেছিল এবং তাই সর্বদা পরিবর্তিত হবে। ব্যতিক্রমী উপাদানটির নাম দেওয়া হয়েছে 'ਰਿਪੋਰਟিংপরিয়ড' এবং হার্ড-কোডড ফাংশনে 'hasFormChanged ()' রয়েছে।

পরীক্ষা করার জন্য, একটি উপাদানটিকে "চেঞ্জের রিপোর্টিংপরিড ()" ফাংশনটি কল করুন, যা আপনি সম্ভবত অন্য কোনও নাম রাখতে চাইবেন।

গুরুত্বপূর্ণ: মানগুলি যখন তাদের মূল মানগুলিতে সেট করা থাকে (সাধারণত পৃষ্ঠার লোড এ, তবে আমার ক্ষেত্রে নয়) আপনাকে অবশ্যই সেট ইনটালিয়ালভ্যালু () কল করতে হবে।

দ্রষ্টব্য: আমি দাবি করি না যে এটি একটি মার্জিত সমাধান, বাস্তবে আমি মার্জিত জাভাস্ক্রিপ্ট সমাধানগুলিতে বিশ্বাস করি না। জাভাস্ক্রিপ্টে আমার ব্যক্তিগত জোর পড়ার যোগ্যতার উপর, কাঠামোগত কমনীয়তা নয় (যেন জাভাস্ক্রিপ্টে সম্ভব হয়েছিল)। জাভাস্ক্রিপ্ট লেখার সময় আমি নিজেকে ফাইলের আকার নিয়ে মোটেই উদ্বেগ করি না কারণ জিজেপ এটিই, এবং আরও কমপ্যাক্ট জাভাস্ক্রিপ্ট কোড লেখার চেষ্টা করা রক্ষণাবেক্ষণে অবিরাম অসুবিধা সৃষ্টি করে। আমি কোন ক্ষমা চাই না, কোনও অনুশোচনা প্রকাশ করি না এবং এটি নিয়ে বিতর্ক করতে অস্বীকার করি। এটি জাভাস্ক্রিপ্ট। দুঃখিত, আমাকে পোস্টিংয়ে বিরক্ত করা উচিত বলে নিজেকে বোঝানোর জন্য আমাকে এই পরিষ্কার করতে হয়েছিল। খুশী থেকো! :)


    var initial_values = new Array();

    // Gets all form elements from the entire document.
    function getAllFormElements() {
        // Return variable.
        var all_form_elements = Array();

        // The form.
        var form_activity_report = document.getElementById('form_activity_report');

        // Different types of form elements.
        var inputs = form_activity_report.getElementsByTagName('input');
        var textareas = form_activity_report.getElementsByTagName('textarea');
        var selects = form_activity_report.getElementsByTagName('select');

        // We do it this way because we want to return an Array, not a NodeList.
        var i;
        for (i = 0; i < inputs.length; i++) {
            all_form_elements.push(inputs[i]);
        }
        for (i = 0; i < textareas.length; i++) {
            all_form_elements.push(textareas[i]);
        }
        for (i = 0; i < selects.length; i++) {
            all_form_elements.push(selects[i]);
        }

        return all_form_elements;
    }

    // Sets the initial values of every form element.
    function setInitialFormValues() {
        var inputs = getAllFormElements();
        for (var i = 0; i < inputs.length; i++) {
            initial_values.push(inputs[i].value);
        }
    }

    function hasFormChanged() {
        var has_changed = false;
        var elements = getAllFormElements();

        for (var i = 0; i < elements.length; i++) {
            if (elements[i].id != 'reporting_period' && elements[i].value != initial_values[i]) {
                has_changed = true;
                break;
            }
        }

        return has_changed;
    }

    function changeReportingPeriod() {
        alert(hasFormChanged());
    }



3

ফর্ম পরিবর্তনগুলি jQuery ছাড়াই দেশীয় জাভাস্ক্রিপ্টে সহজেই সনাক্ত করা যায়:

function initChangeDetection(form) {
  Array.from(form).forEach(el => el.dataset.origValue = el.value);
}
function formHasChanges(form) {
  return Array.from(form).some(el => 'origValue' in el.dataset && el.dataset.origValue !== el.value);
}


initChangeDetection()আপনার পৃষ্ঠার জীবনকালক্রমে নিরাপদে একাধিকবার কল করা যেতে পারে: জেএসবিনে পরীক্ষা দেখুন


পুরানো ব্রাউজারগুলির জন্য যারা নতুন তীর / অ্যারে ফাংশন সমর্থন করে না:

function initChangeDetection(form) {
  for (var i=0; i<form.length; i++) {
    var el = form[i];
    el.dataset.origValue = el.value;
  }
}
function formHasChanges(form) {
  for (var i=0; i<form.length; i++) {
    var el = form[i];
    if ('origValue' in el.dataset && el.dataset.origValue !== el.value) {
      return true;
    }
  }
  return false;
}

আমার ফর্মটির জন্য সর্বদা সত্য ফিরে আসে
ধনী স্টোন

আপনি কি আপনার ফর্মটি জেএসবিনে বা কোনও সংকেত পোস্ট করতে পারেন যাতে আমরা আপনার ফর্মটি দেখতে পারি?
অ্যান্থমক্রিস

আমার দোষ, আমি jquery দিয়ে ফর্মটি নির্বাচন করেছি এবং আপনার উদাহরণ হিসাবে জেএসের সাথে নয়। সিরিয়ালাইজেশন ওভারলোড ছাড়াই এটি একটি দুর্দান্ত এবং পরিষ্কার জেএস সমাধান। ধন্যবাদ!
ধনী পাথর

2

নেটিভ জাভাস্ক্রিপ্টে একটি পলিফিল পদ্ধতির ডেমো রয়েছে যা FormData()তৈরি, আপডেট এবং মুছে ফর্ম এন্ট্রি সনাক্ত করতে API ব্যবহার করে । ব্যবহার করে কিছু পরিবর্তন করা হয়েছে কিনা তা আপনি পরীক্ষা করে দেখতে পারেন HTMLFormElement#isChangedএবং রিসেট ফর্মটি ব্যবহার করে কোনও পার্থক্য সম্বলিত একটি বস্তুটি ব্যবহার করে HTMLFormElement#changes(ধরে নিবেন যে তারা কোনও ইনপুট নামের দ্বারা মুখোশপ্রাপ্ত নয়):

Object.defineProperties(HTMLFormElement.prototype, {
  isChanged: {
    configurable: true,
    get: function isChanged () {
      'use strict'

      var thisData = new FormData(this)
      var that = this.cloneNode(true)

      // avoid masking: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset
      HTMLFormElement.prototype.reset.call(that)

      var thatData = new FormData(that)

      const theseKeys = Array.from(thisData.keys())
      const thoseKeys = Array.from(thatData.keys())

      if (theseKeys.length !== thoseKeys.length) {
        return true
      }

      const allKeys = new Set(theseKeys.concat(thoseKeys))

      function unequal (value, index) {
        return value !== this[index]
      }

      for (const key of theseKeys) {
        const theseValues = thisData.getAll(key)
        const thoseValues = thatData.getAll(key)

        if (theseValues.length !== thoseValues.length) {
          return true
        }

        if (theseValues.some(unequal, thoseValues)) {
          return true
        }
      }

      return false
    }
  },
  changes: {
    configurable: true,
    get: function changes () {
      'use strict'

      var thisData = new FormData(this)
      var that = this.cloneNode(true)

      // avoid masking: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/reset
      HTMLFormElement.prototype.reset.call(that)

      var thatData = new FormData(that)

      const theseKeys = Array.from(thisData.keys())
      const thoseKeys = Array.from(thatData.keys())

      const created = new FormData()
      const deleted = new FormData()
      const updated = new FormData()

      const allKeys = new Set(theseKeys.concat(thoseKeys))

      function unequal (value, index) {
        return value !== this[index]
      }

      for (const key of allKeys) {
        const theseValues = thisData.getAll(key)
        const thoseValues = thatData.getAll(key)

        const createdValues = theseValues.slice(thoseValues.length)
        const deletedValues = thoseValues.slice(theseValues.length)

        const minLength = Math.min(theseValues.length, thoseValues.length)

        const updatedValues = theseValues.slice(0, minLength).filter(unequal, thoseValues)

        function append (value) {
          this.append(key, value)
        }

        createdValues.forEach(append, created)
        deletedValues.forEach(append, deleted)
        updatedValues.forEach(append, updated)
      }

      return {
        created: Array.from(created),
        deleted: Array.from(deleted),
        updated: Array.from(updated)
      }
    }
  }
})

document.querySelector('[value="Check"]').addEventListener('click', function () {
  if (this.form.isChanged) {
    console.log(this.form.changes)
  } else {
    console.log('unchanged')
  }
})
<form>
  <div>
    <label for="name">Text Input:</label>
    <input type="text" name="name" id="name" value="" tabindex="1" />
  </div>

  <div>
    <h4>Radio Button Choice</h4>

    <label for="radio-choice-1">Choice 1</label>
    <input type="radio" name="radio-choice-1" id="radio-choice-1" tabindex="2" value="choice-1" />

    <label for="radio-choice-2">Choice 2</label>
    <input type="radio" name="radio-choice-2" id="radio-choice-2" tabindex="3" value="choice-2" />
  </div>

  <div>
    <label for="select-choice">Select Dropdown Choice:</label>
    <select name="select-choice" id="select-choice">
      <option value="Choice 1">Choice 1</option>
      <option value="Choice 2">Choice 2</option>
      <option value="Choice 3">Choice 3</option>
    </select>
  </div>

  <div>
    <label for="textarea">Textarea:</label>
    <textarea cols="40" rows="8" name="textarea" id="textarea"></textarea>
  </div>

  <div>
    <label for="checkbox">Checkbox:</label>
    <input type="checkbox" name="checkbox" id="checkbox" />
  </div>

  <div>
    <input type="button" value="Check" />
  </div>
</form>

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.