vue idb format variable - vuejs2

Hello I'm making a web app using vuex and vue idb.
In one of my view I have a table with filter fields.
My data are stored using vue-idb and filter fields call applyFilter methods function using the input text box event and the header name of the column's cell
Here is my html
...some html
<!--columns filters-->
<tr>
<td v-if='shownHeaders.length > 0'>
<input type='checkbox' #change='updateCheckboxList(-1)' :checked='checkAllCheckbox'>
</td>
<td v-for='(header,index) in headers' v-if='headers.indexOf(header)>-1'>
<input #keyup="applyFilter(header,$event )" :disabled="thinking" :placeholder='header +" filter"'>
</td>
</tr>
Here is my component
some code ...
applyFilter (header, e) {
// apply filter after enter key has been pressed
if (e.keyCode === 13) {
console.log('Filtering column ' + header + ' with ' + e.target.value)
// not working unsing dynamical variable, but it does while using static variable like uid
store.dispatch('tasksSetFilter', {header: e.target.value}) // this doesn't works
// store.dispatch('tasksSetFilter', {id: e.target.value}) // this works
My issue is that I'm unable to use header variable (a string) as key of dict passed with tasksSetFilter, but if I replace it by a variable having the same name it works.
Is there a way to transform string to variable name to solve my problem?

Try this:
store.dispatch('tasksSetFilter', {[header]: e.target.value})
What this syntax does is set the parameter to an object where the key will be whatever the value of header is. This is a newer syntax that came about with ES2015.
If you could not support ES2015, you could build the parameter this way:
let filter = {}
filter[header] = e.target.value
store.dispatch('tasksSetFilter', filter)

Related

Send Dynamic Table as Model back to the controller

I would like to send a dynamic table back to the controller by using its model.
Following situation. On the view I am creating a table with javascript which allows the users to insert different values. These values are picked from pre-defined comboboxes:
$(document).ready(function () {
$('#btn_insert').on('click', function ()
var table=document.getElementById("table_computerimport");
var table_len=(table.rows.length)-1;
var row = table.insertRow(table_len).outerHTML="<tr id='row"+table_len+"'><td id='computername_row"+table_len+"'>"+computername+"</td><td id='uuid_row"+table_len+"'>"+"HERE UUID"+"</td><td id='collection_row"+table_len+"'>"+" HERE Collection Name"+"</td><td><input type='button' value='Delete' class='delete' onclick='delete_row("+table_len+")'></td></tr>";
});
This is working fine, so that at least the table is created with n entries.
<div>
<button type="button" id="btn_insert" class="btn btn-primary">Insert</button>
<div >
<table class="table" id="table_computerimport">
<thead>
<tr>
<th>Hostname</th>
<th>MacAddress</th>
<th>GUID</th>
</tr>
</thead>
<tr>
</tr>
</table>
</div>
</div>
These entries I would like to pass back to the controller by using its model:
public IEnumerable<ComputerImportModel> TableComputerImport {get; set;}
#model ViewModels.ComputerImportViewModel
So I don’t want to loop though the list of objects and publish them in the view, I would like to create n records in one view at once and pass these back to the controller by using the model TableComputerImport.
I guess in Javascript somehow I have to say something like this: input asp-for="ComputerImport.hostname"
Update,
ok, I think I "solved" it. What I did is that I created an array with javascript out of the table and passed this by ajax to the controller. It was important that the array has the name attributes like the class does so that I can use this object in the constructor as a well defined object.
As I mentioed, I had to use an array which I send by AJAX to the controller. Because of the identical names in the table and in the model, everything goes its correct way:
var singlecomputerimport = [];
var headers = [];
$('#table_computerimport th').each(function(index, item) {
headers[index] = $(item).html();
});
$('#table_computerimport tr').has('td').each(function() {
var arrayItem = {};
$('td', $(this)).each(function(index, item) {
if(headers[index] !== undefined){
//console.log($(item));
//arrayItem[headers[index].toLowerCase()] = $(item).html();
arrayItem[headers[index].toLowerCase()] = $(item).attr('value');
}
});
singlecomputerimport.push(arrayItem);
});

I need help in calling watcher in Vuejs2 when looping the objects in HTML

I am adding one object when clicking on button and displaying the same in HTML. User can able to select the drop down values in options (string or number). Based on the input, need to disable or enable the next text input field. Here is my HTML code,
<table>
<tr><button #click="add_new_input()">Add </button></tr>
<tr v-for="(key, index) in NewArr" v-bind:key=value>
<td>
<multiselect
v-model="key.name"
:options="NameList"
selectLabel='select'
#input="userInput(value)"
></multiselect>
</td>
<td class="modify-td-padding__multi">
<input type="text"
v-model="key.value"
:disabled="isNumber"
class="input-increase-height">
</td>
</tr>
</table>
if we change the key.name dropdown, it will call one function userInput() using #input. passing value will be either "string" or "number". Vue Mehods is below,
userInput: function (value) {
this.getInputType(value);
},
getInputType: function (value) {
if(value === "string") {
this.isNumber = false;
} else {
this.isNumber = true;
}
},
add_new_input: function () {
let vm = this;
vm.NewArr.push({
name: '',
value: '',
});
vm.$set(vm.NewArr, vm.name, vm.value);
}
add_new_input will add new object to NewArr, getInputType function will check the value is "string" or "number". If it is "string", text field should be disabled else enabled.
My issue is, if there are two rows, and if i am selecting key.name for 2nd row, it is affecting the first row input field also(key.name for both rows getting enabled or disabled). I need to make change only the specific text field. So, all the text fields becoming disabled even it is "number".
This is my first project in VueJS. Thanks a lot if anyone helps me on this. Thanks in advance.
You need to manage isNumber per key, so not just
data() {return {isNumber: false}}
But:
#input="userInput(key.name, value)"
:disabled="isNumber[key.name]"
data(){ return { isNumber: {} }}
...
onUserInput: function (key, value) {
this.setIsNumber(key, value);
},
setIsNumber: function (key, value) {
this.$set(this.isNumber, key, value !== "string");
},

ASP.NET MVC 4 Passing Object Variable Through ActionLink

I have an ASP.NET MVC 4 application. There is a razor view in my application that works with List type as a model.
#model List<MeetingLog.Models.UserModel>
#{
Layout = null;
}
.
.
.
I am iterating through Model variable like this:
#foreach (var item in Model)
{
<tr>
<td>
#item.Name
</td>
<td>
#item.Surname
</td>
<td>
#Html.ActionLink("Click", "SavePerson", "Meeting", new {model = item, type = "coordinator"}, null)
#Html.ActionLink("Click", "SavePerson", "Meeting", new {model = item, type = "participant"}, null)
</td>
</tr>
}
I need to pass two variables to SavePerson action with action links. First one is current UserModel, and second one is string variable named type. But in my action first parameter comes through as null. But string parameter comes correctly. How can I achieve this?
I use ajax calls for this
$('.btnSave').on('click', function(){
$.ajax({
url: '#(Url.Action("SavePerson", "Meeting"))',
type: 'post',
data: {
Value1: 'Value1',
Value2: 'Value2'
},
success: function (result) {
alert('Save Successful');
}
});
});
and put the call in a button click or a link click if you want with href = # hopefully this helps.
You can not pass instances complex types through querystring. This is the way to use it:
#Html.ActionLink("Click", "SavePerson", "Meeting", new {x = item.x, y = item.y, ..., type = "participant"}, null)
You actually can, it's just a little weird, when you are coding the passed values (new{})
what you have to do is pass it as a new object that you are constructing so it ends up being:
#Html.ActionLink("Link Name", "LinkActionTarget", new Object{model = item, type ='Coordinator'}
Where Object is the name of your object, and model and type are attributes of that object

Detecting Selected Row in html table Knockout/ASP.NET MVC

I've loaded an ASP.NET MVC viewModel into KnockoutJS using ko.mapping.fromJS(Model).
My viewModel looks something like this:
public IEnumerable<FunkyThing>funkyThings;
public FunkyThing selectedFunkyThing;
I've then got in my HTML View a table which looks something like this
<tbody data-bind="foreach: funkyThings">
<tr>
<td data-bind="text:name"></td>
<td data-bind="text:funkiness"></td>
<td>
</td>
</tr>
</tbody>
and all is good with this table. Clicking the select funky thing link happily calls the selectFunkyThing function:
model.selectFunkyThing= function (funkyThing) {
window.location = '#Url.Action(MVC.FunkyThingController.Index())' + "?funkyThingID=" + funkyThing.funkyThingID();
};
which in turn refreshes the page. The MVC viewmodels is reloaded and selectedFunkyThing is populated with the selected FunkyThing and the knockout view models are then re-read from the MVC viewmodel. So far so good.
I then wanted to update the table to highlight the selected entry.
So I updated the tr line as follows:
<tr data-bind="css:{'selected': $root.isSelected()}">
and created the new knockout function:
model.isSelected = function (funkyThing) {
return funkyThing.funkyThingID== model.selectedFunkyThing.funkyThingID;
};
but... it's not working.
Chrome throws a javascript exception stating that the FunkyThing parameter is undefined.
Technically I figure I could solve it by changing the MVC viewModel to actually set a isSelected on each FunkyThing within the array. However I figure there's got to be away of doing this from Knockout?
You were close! I added the ko.utils.unwrapObservable call because I bet the funkyThingID is an observable and not just a straight property - you did this yourself in your selectFunkyThing function. You could just execute them as well. I like the verbosity of unwrap though.
model.isSelected = function (funkyThing) {
var thisId = ko.utils.unwrapObservable(model.selectedFunkyThing.funkyThingID);
return ko.utils.unwrapObservable(funkyThing.funkyThingID) == thisId;
};
and then in your document you actually have to execute this function when ko parses the binding
<tr data-bind="css:{'selected': $root.isSelected($data)}">
Are those properties not both observables, so you need to reference them as functions? You also need to make your function a computed observable, I think:
model.isSelected = ko.computed(function (funkyThing) {
return funkyThing().funkyThingID() == model.selectedFunkyThing().funkyThingID();
});

How to pass extra variables and parameters to jQote2?

I have a couple Javascript functions which concatenates a URL which I set to the variable c. I then try to pass that variable into jQote2:
$.get("emptyReq.tpl", function(tmpl,c) {
$("#reqs").jqoteapp(tmpl, result, c);
});
In emptyReq.tmpl, I'm doing the following:
<tr id="row">
<td name="id" class="id"><%= this.FormattedID %></td>
<td name="name" class="name"><%= this._refObjectName %></td>
<td name="state" class="state"><%= this.ScheduleState %></td>
<td name="owner" class="owner"></td>
</tr>
I've tried a couple of variations (this.c and c) and I've also tried different variables, but I'm not able to get the URL to display correctly.
c is labeled as undefined in the console, and the URL ends up being something like: http://127.0.0.1/xampp/py2/undefined instead of the actual c which is something like https://rally1.rallydev.com/slm/rally.sp#/2735190513d/detail/userstory/4599269614
Is there a way to pass the parameters properly? Or am I supposed to do the concatenation in the .tmpl file itself?
Here is what I've been using as a reference: jQote Reference.
rishimaharaj,
the jqoteapp method's third paramter is used to change the template tag (<% ... %> by default) on a per call basis. If you need to pass additional data to your template you have two options:
Make c a global variable (I wouldn't recommend that, though)
Copy c's value to the data parameter (recommended):
Please be aware that the copying needs to take into account of what type your
templating data is, i.e. a single object is handled different from an array of
objects!
$.get("emptyReq.tpl", function(tmpl,c) {
var data;
// 'result' seems to be a global var, thus making a copy is a good idea.
// Copying needs to take into account the type of 'result'
if ( Object.prototype.toString(result) === '[object Array]' ) {
data = result.slice(0);
} else {
data = [$.extend({}, result)];
}
// Now it is safe to add 'c' to the wrapping array. This way
// we won't override any homonymous property
data.c = c;
// Call the processing with our local copy
$("#reqs").jqoteapp(tmpl, data);
});
Once you've changed this, you will be able to access c through the templating
lamda's inherent property data:
<tr id="row">
... <a href="<%= data.c %>"><%= this.FormattedID ...
</tr>
Regards,
aefxx