This is a migrated thread and some comments may be shown as answers.

Copy DropDownList copied but not working

1 Answer 400 Views
DropDownList
This is a migrated thread and some comments may be shown as answers.
Ursus
Top achievements
Rank 1
Iron
Ursus asked on 31 Oct 2019, 09:14 AM

I have multiple dropdown fields on a form.The form might start off with 3 fields, I want the user to be able to add extra dropdown fields (see the attached screenshot). Lets say the customer currently has 3 machines but has just bought a fourth one. I display the company document showing the three machines, the user presses the + button to create a new entry and then selects the correct machine from the dropdown. I have the copying of the field working, the problem is that the DropDownList ist not getting populated i.e. the .read of the datasource is not being called (at least that is what I think is happening). I assume I need to call the init (.kendoAutoComplete) function somehow, cannot figure out how though. Any pointers would be great!

 

Here the DropDownField I am trying to copy: 

@(Html.Kendo().DropDownList()
      .Name(kendoFieldName)
      .MinLength(3)
      .Value(Model.Fields[i].Values[j])
      .HtmlAttributes(new {style = "width: 100%"})
      .Filter(FilterType.Contains)
      .DataSource(source =>
      {
          source.Read(read =>
          {
              read.Action("TypeAhead", "Document", new
              {
                  docId = Model.DocId,
                  docType = Model.DocType,
                  fieldNumber = Model.Fields[i].FieldIndex,
                  row = j,
                  currentValue = Model.Fields[i].Values[j]
              });
          })
          .ServerFiltering(true);
      })
      )

 

The clone button is:

<button id="plusButton" type="button" class="btn" onclick="addRow(@i, @j, @Model.Fields[i].Values.Count);">
    <i class="fa fa-plus fa-lg"></i>
</button>

 

And finally the addRow function:

//
// Add a new div to the page
//
var newRowNumber = 0;
 
function addRow(field, value, numberOfValues) {
 
    var rowId = `row_field_${field}_value_${value}`;
    var fieldId = `field_${field}_value_${value}`;
    var originalFieldId = `original_field_${field}_value_${value}`;
    var newRowId = `row_field_${field}_value_${numberOfValues + newRowNumber}`;
    var newFieldId = `field_${field}_value_${numberOfValues + newRowNumber}`;
    var newFieldName = `Fields[${field}].Values[${numberOfValues + newRowNumber}]`;
    var addFunction = `addRow(${field}, ${numberOfValues + newRowNumber}, ${numberOfValues})`;
    var removeFunction = `removeRow('${newRowId}')`;
 
    // get the current row
    const currentRow = $(`#${rowId}`);
    if (!currentRow.length) return;
 
    newRowNumber++;
 
    // clone the row
    var newRow = currentRow.clone();
    newRow.attr("id", newRowId);
 
    // update the value field
    var newField = newRow.find(`#${fieldId}`);
    newField.val("");
    newRow.find(`#${fieldId}`).attr({ name: newFieldName });
    newRow.find(`#${fieldId}`).attr({ id: newFieldId });
    newRow.find(`#${fieldId}`).attr({ value: "" });
 
    // remove the stuff you don't need
    newRow.find(`#${originalFieldId}`).remove();
    newRow.find("#minusButton").remove();
    newRow.find("#plusButton").remove();
    newRow.find("#labelForField").remove();
 
    // add minus button
    var plusButton = `<button id="plusButton" type="button" class="btn" onclick="${addFunction};"><i class="fa fa-plus fa-lg"></i></button>`;
    var minusButton = `<button id="minusButton" type="button" class="btn" onclick="${removeFunction};"><i class="fa fa-minus fa-lg"></i></button>`;
    newRow.find("#buttons").append(plusButton);
    newRow.find("#buttons").append(minusButton);
     
    // add the new row
    $(currentRow).after(newRow);
 
}
//
// remove a div on the age
//
function removeRow(rowId) {
 
    // get the current row
    // need to add the trim here as using template strings above added a extra space to the literal? see removeFunctions(" values")
    const currentRow = $(`#${rowId.trim()}`);
    if (!currentRow.length) return;
 
    // remove the row
    currentRow.remove();
 
}

 

 

 

 

1 Answer, 1 is accepted

Sort by
0
Ursus
Top achievements
Rank 1
Iron
answered on 03 Nov 2019, 04:21 PM

After much testing I have found my error - the problem seems to be when I copied the whole row and then tried to add etc. the elements - better is if you create your row anew and then just clone the input field *and* then initialise it using the following code

 

var originalWidgetType = "kendo" + window.kendo.widgetInstance(fieldToCopy).options.name;
var originalWidget = fieldToCopy.data(originalWidgetType);
newField[originalWidgetType](originalWidget.options);

 

I have attached the whole bit of JavaScript code should anyone need it.

 

// get the current row
var currentRowId = `row_field_${fieldNo}_value_${rowNo}`;
const currentRow = $(`#${currentRowId}`);
if (!currentRow.length) return;
 
// create a new, empty row, and add it below the current row
var newRowNo = maxRowNo + rowsAdded;
var newRowId = `row_field_${fieldNo}_value_${newRowNo}`;
$(currentRow).after("<div id=" + newRowId + " class=\"form-group row\"></div>");
 
// get the row you just created
var newRow = $(`#${newRowId}`);
if (!newRow.length) return;
 
// just some vars to make the code easier to read
var labelColumn = "<div id=\"label\" class=\"col-sm-3\">";
var fieldColumn = "<div id=\"field\" class=\"col-sm-7\">";
var buttonsColumn = "<div id=\"buttons\" class=\"col-sm-2\">";
 
// append your columns
newRow.append(labelColumn);
newRow.append(fieldColumn);
newRow.append(buttonsColumn);
 
// add the new plus and minus button
var addFunction = `addRow(${fieldNo}, ${newRowNo}, ${maxRowNo})`;
var removeFunction = `removeRow(${fieldNo}, ${newRowNo})`;
var plusButton = `<button id="plusButton" type="button" class="btn" onclick="${addFunction};"><i class="fa fa-plus fa-lg"></i></button>`;
var minusButton = `<button id="minusButton" type="button" class="btn" onclick="${removeFunction};"><i class="fa fa-minus fa-lg"></i></button>`;
newRow.find("#buttons").append(plusButton);
newRow.find("#buttons").append(minusButton);
 
// clone the field
var newFieldId = `Fields_${fieldNo}__Values_${newRowNo}_`;
var newFieldName = `Fields[${fieldNo}].Values[${newRowNo}]`;
var oldFieldId = `Fields_${fieldNo}__Values_${rowNo}_`;
var fieldToCopy = currentRow.find("#" + oldFieldId);
fieldToCopy
    .clone()
    .attr("id", newFieldId)
    .attr("name", newFieldName)
    .appendTo('#field');
 
// get the field you just cloned
var newField = $(`#${newFieldId}`);
if (!newField.length) return;
 
// now initialise the field
var originalWidgetType = "kendo" + window.kendo.widgetInstance(fieldToCopy).options.name;
var originalWidget = fieldToCopy.data(originalWidgetType);
newField[originalWidgetType](originalWidget.options);

 

 

Tags
DropDownList
Asked by
Ursus
Top achievements
Rank 1
Iron
Answers by
Ursus
Top achievements
Rank 1
Iron
Share this question
or