Bug 8064: Change the way target record is built.
authorJulian Maurice <julian.maurice@biblibre.com>
Wed, 6 Nov 2013 11:17:45 +0000 (12:17 +0100)
committerTomas Cohen Arazi <tomascohen@theke.io>
Mon, 9 Nov 2015 18:08:57 +0000 (15:08 -0300)
Instead of copying/removing a piece of DOM in target record each time a
checkbox is checked/unchecked, the target record is *entirely* rebuilt
each time a checkbox is checked/unchecked.
This is slower but allow for a more consistent and less error-prone
behaviour.

This patch also fix the mandatory check for subfields

Signed-off-by: Bernardo Gonzalez Kriegel <bgkriegel@gmail.com>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
koha-tmpl/intranet-tmpl/prog/en/includes/merge-record-strings.inc
koha-tmpl/intranet-tmpl/prog/en/includes/merge-record.inc
koha-tmpl/intranet-tmpl/prog/en/js/merge-record.js
koha-tmpl/intranet-tmpl/prog/en/modules/cataloguing/merge.tt

index 6b04e54..66c55c4 100644 (file)
@@ -1,5 +1,5 @@
 [%# transletable strings for merge-record.js %]
 <script type="text/javascript">
     var MSG_MERGEREC_ALREADY_EXISTS = _("The field is non-repeatable and already exists in the destination record. Therefore, you cannot add it.");
-    var MSG_MERGEREC_SUBFIELD   = _("This subfield cannot be added: there is no %s field in the destination record.");
-</script>
\ No newline at end of file
+    var MSG_MERGEREC_SUBFIELD_ALREADY_EXISTS = _("The subfield is non-repeatable and already exists in the destination record. Therefore, you cannot add it.");
+</script>
index 4752515..111252a 100644 (file)
 <div id="result">
     <h2>Destination record</h2>
     <div style="border:1px solid #E8E8E8;padding:1em;margin-top:2em;">
-        <ul id="resultul">
-          [% FOREACH field IN ref_record.display %]
-            [% IF field.tag != biblionumbertag %]
-              <li id="k[% field.key %]">
-                <span class="field">[% field.tag %]</span>
-                <input type="hidden" name="tag_[% field.tag %]_indicator1_[% field.key %]" value="[% field.indicator1 %]" />
-                <input type="hidden" name="tag_[% field.tag %]_indicator2_[% field.key %]" value="[% field.indicator2 %]" />
-                [% IF ( field.value ) %]
-                  / [% field.value %]
-                  <input type="hidden" name="tag_[% field.tag %]_code_00_[% field.key %]" value="00" />
-                  <input type="hidden" name="tag_[% field.tag %]_subfield_00_[% field.key %]" value="[% field.value |html%]" />
-                [% END %]
-
-                [% IF ( field.subfield ) %]
-                  <ul>
-                    [% FOREACH subfield IN field.subfield %]
-                      <li id="k[% subfield.subkey %]">
-                        <span class="subfield">[% subfield.subtag %]</span> / [% subfield.value %]
-                        <input type="hidden" name="tag_[% field.tag %]_code_[% subfield.subtag %]_[% field.key %]_[% subfield.subkey %]" value="[% subfield.subtag %]" />
-                        <input type="hidden" name="tag_[% field.tag %]_subfield_[% subfield.subtag %]_[% field.key %]_[% subfield.subkey %]" value="[% subfield.value |html%]" />
-                      </li>
-                    [% END %]
-                  </ul>
-                [% END %]
-              </li>
-            [% END %]
-          [% END %]
-        </ul>
-</div>
+        <ul id="resultul"></ul>
+    </div>
 </div> <!-- // #result -->
 [% END %]
index 80de586..ab74e1a 100644 (file)
  * Merging 2 source records into a destination record
  */
 
-/**
- * Check or uncheck a field or subfield in a source record
- * @param pField the checkbox clicked
- */
-function toggleField(pField) {
-
-    // Getting the key of the clicked checkbox
-    var ckid   = $(pField).attr("id");
-    var tab    = ckid.split('_');
-    var source = tab[1]; // From which record the click came from
-    var key    = tab[2];
-    var type   = $(pField).attr("class");
-
-    // Getting field/subfield
-    var field;
-    var subfield;
-    if (type == "subfieldpick") {
-        field = $(pField).parent().parent().parent().find("span.field").text();
-        subfield = $(pField).parent().find("span.subfield").text();
+function build_target_record($sources) {
+  var target_record = {};
+
+  $sources.find('.record input[type="checkbox"].fieldpick:checked').each(function() {
+    var $checkbox = $(this);
+    var $li = $checkbox.parent();
+    var field = $checkbox.parent().find("span.field").text();
+
+    if (!(field in target_record)) {
+      target_record[field] = [];
+    }
+    target_record[field].push({
+      'id' : $li.attr('id'),
+      'tag' : field,
+      'subfields' : []
+    });
+  });
+
+  $sources.find('.record input[type="checkbox"].subfieldpick:checked').each(function() {
+    var $checkbox = $(this);
+    var $li = $checkbox.parent();
+    var $field_li = $li.parents('li');
+    var field = $field_li.find('span.field').text();
+    var subfield = $li.find('span.subfield').text();
+
+    var target_field;
+    if (field in target_record) {
+      for (i in target_record[field]) {
+        if (target_record[field][i].id == $field_li.attr('id')) {
+          target_field = target_record[field][i];
+        }
+      }
+      if (!target_field) {
+        target_field = target_record[field][0];
+      }
+    }
+    if (target_field) {
+      target_field.subfields.push({
+        'id' : $li.attr('id'),
+        'code' : subfield
+      });
     } else {
-        field = $(pField).parent().find("span.field").text();
+      $field_li.find('input.fieldpick').attr('checked', true);
+      target_record[field] = [{
+        'id' : $field_li.attr('id'),
+        'tag' : field,
+        'subfields' : [{
+          'id' : $li.attr('id'),
+          'code' : subfield
+        }]
+      }];
     }
+  });
 
-    // If the field has just been checked
-    if (pField.checked) {
-
-        // We check for repeatability
-        var canbeadded = true;
-        if (type == "subfieldpick") {
-            var repeatable = 1;
-            var alreadyexists = 0;
-            if (tagslib[field] && tagslib[field][subfield]) {
-                // Note : we can't use the dot notation here (tagslib.021) because the key is a number
-                repeatable = tagslib[field][subfield].repeatable;
-                // TODO : Checking for subfields
-            }
-        } else {
-            if (tagslib[field]) {
-                repeatable = tagslib[field].repeatable;
-                alreadyexists = $("#resultul span.field:contains(" + field + ")");
-                if (repeatable == 0 && alreadyexists.length != 0) {
-                    canbeadded = false;
-                }
-            }
+  return target_record;
+}
+
+function field_can_be_added($sources, $li) {
+  target_record = build_target_record($sources);
+
+  var tag = $li.find('span.field').text();
+  var repeatable = true;
+  if (tag in tagslib) {
+    repeatable = (tagslib[tag].repeatable != 0) ? true : false;
+  }
+
+  if ((!repeatable) && (tag in target_record)) {
+    alert(MSG_MERGEREC_ALREADY_EXISTS);
+    return false;
+  }
+
+  return true;
+}
+
+function subfield_can_be_added($sources, $li) {
+  target_record = build_target_record($sources);
+
+  var $field_li = $li.parents('li');
+  var tag = $field_li.find('span.field').text();
+  var code = $li.find('span.subfield').text();
+
+  var repeatable = true;
+  if (tag in tagslib && code in tagslib[tag]) {
+    repeatable = (tagslib[tag][code].repeatable != 0) ? true : false;
+  }
+
+  if (!repeatable) {
+    var target_field;
+    if (tag in target_record) {
+      for (i in target_record[tag]) {
+        if (target_record[tag][i].id == $field_li.attr('id')) {
+          target_field = target_record[tag][i];
+        }
+      }
+      if (!target_field) {
+        target_field = target_record[tag][0];
+      }
+    }
+    if (target_field) {
+      for (i in target_field.subfields) {
+        var subfield = target_field.subfields[i];
+        if (code == subfield.code) {
+          alert(MSG_MERGEREC_SUBFIELD_ALREADY_EXISTS);
+          return false;
         }
+      }
+    }
+  }
+
+  return true;
+}
 
-        // If the field is not repeatable, we check if it already exists in the result table
-        if (canbeadded == false) {
-            alert(MSG_MERGEREC_ALREADY_EXISTS);
-            pField.checked = 0;
-        } else {
-
-            // Cloning the field or subfield we picked
-            var clone = $(pField).parent().clone();
-
-            // Removing the checkboxes from it
-            $(clone).find("input.subfieldpick, input.fieldpick").each(function() {
-                $(this).remove();
-            });
-
-            // If we are a subfield
-            if (type == "subfieldpick") {
-                // then we need to find who is our parent field...
-                fieldkey = $(pField).parent().parent().parent().attr("id");
-
-                // Find where to add the subfield
-
-                // First, check if the field is not already in the destination record
-                if ($("#resultul li#" + fieldkey).length > 0) {
-
-                    // If so, we add our field to it
-                    $("#resultul li#" + fieldkey + " ul").append(clone);
-                } else {
-
-                    // If not, we add the subfield to the first matching field
-                    var where = 0;
-                    $("#resultul li span.field").each(function() {
-                        if ($(this).text() == field) {
-                            where = this;
-                            return false; // break each()
-                        }
-                    });
-
-                    // If there is no matching field in the destination record
-                    if (where == 0) {
-
-                        // TODO:
-                        // We select the whole field and removing non-selected subfields, instead of...
-
-                        // Alerting the user
-                        alert(MSG_MERGEREC_SUBFIELD.format(field));
-                        pField.checked = false;
-                    } else {
-                        $(where).nextAll("ul").append(clone);
-                    }
-
-                }
-
-            } else {
-                // If we are a field
-                var where = 0;
-                // Find a greater field to add before
-                $("#resultul li span.field").each(function() {
-                    if ($(this).text() > field) {
-                        where = this;
-                        return false; // break each()
-                    }
-                });
-                if (where) {
-                    $(where).parent().before(clone);
-                } else {
-                    // No greater field, add to the end
-                    $("#resultul").append(clone);
-                }
-            }
+function rebuild_target($sources, $target) {
+  target_record = build_target_record($sources);
+
+  $target.empty();
+  var keys = $.map(target_record, function(elem, idx) { return idx }).sort();
+  for (k in keys) {
+    var tag = keys[k];
+    var fields = target_record[tag];
+    for (i in fields) {
+      var field = fields[i];
+      if (field.subfields.length > 0) {
+        var $field_clone = $('#' + field.id).clone();
+        $field_clone.find('ul').empty();
+        $field_clone.find('.fieldpick').remove();
+        $target.append($field_clone);
+
+        for (j in field.subfields) {
+          var subfield = field.subfields[j];
+          var $subfield_clone = $('#' + subfield.id).clone();
+          $subfield_clone.find('.subfieldpick').remove();
+          $field_clone.find('ul').append($subfield_clone);
         }
-    } else {
-        // Else, we remove it from the results tab
-        $("ul#resultul li#k" + key).remove();
+      } else {
+        $('#' + field.id).find('input.fieldpick').attr('checked', false);
+      }
     }
+  }
 }
 
 /*
@@ -130,16 +149,24 @@ function toggleField(pField) {
 $(document).ready(function(){
     // When a field is checked / unchecked
     $('input.fieldpick').click(function() {
-        toggleField(this);
         // (un)check all subfields
         var ischecked = this.checked;
+        if (ischecked && !field_can_be_added($('#tabs'), $(this).parent())) {
+          return false;
+        }
+
         $(this).parent().find("input.subfieldpick").each(function() {
             this.checked = ischecked;
         });
+        rebuild_target($('#tabs'), $('#resultul'));
     });
 
     // When a field or subfield is checked / unchecked
     $("input.subfieldpick").click(function() {
-        toggleField(this);
+      var ischecked = this.checked;
+      if (ischecked && !subfield_can_be_added($('#tabs'), $(this).parent())) {
+        return false;
+      }
+      rebuild_target($('#tabs'), $('#resultul'));
     });
 });
index b6495fa..8d1a4d2 100644 (file)
@@ -40,7 +40,7 @@ div#result { margin-top: 1em; }
                 if (tagslib[tag][subfieldcode].mandatory == 1 && tagslib[tag][subfieldcode].tab >= 0) {
                     var fields = $("#resultul span.field:contains("+ tag +")");
                     $(fields).each(function() {
-                        var subfields = $(this).parent().find("span.subfield:contains("+ subfieldcode +")");
+                        var subfields = $(this).parents('li').find("span.subfield:contains("+ subfieldcode +")");
                         if (subfields.length == 0) {
                             missing.subfields.push( {
                                 'tag': tag,
@@ -85,13 +85,10 @@ div#result { margin-top: 1em; }
     }
 
 $(document).ready(function(){
-    // Getting marc structure via ajax
     tagslib = [];
     $.getJSON("/cgi-bin/koha/cataloguing/merge_ajax.pl", {frameworkcode : "[% framework %]" }, function(json) {
-        tagslib = json;
-
-    //Set focus to cataloging search
-    $("input[name=q]:eq(0)").focus();
+      tagslib = json;
+      rebuild_target($("#tabs"), $("#resultul"));
     });
 
     // Creating tabs
@@ -102,6 +99,8 @@ $(document).ready(function(){
     $('#tabs div#tabrecord[% ref_biblionumber %]').find('input[type="checkbox"]').attr('checked', true);
     $('#tabs > div:not("#tabrecord[% ref_biblionumber %]")').find('input[type="checkbox"]').removeAttr('checked');
 
+    //Set focus to cataloging search
+    $("input[name=q]:eq(0)").focus();
 });
 
   [% END %]