Marionette ItemView and radio Buttons - backbone.js

I have data being returned from a server with a status flag. And on each ItemView I have some radio Buttons as follows:
<td><input type='radio' name='<%- id %>-typeRecipe' value='0'></td>
<td><input type='radio' name='<%- id %>-typeRecipe' value='2'></td>
<td><input type='radio' name='<%- id %>-typeRecipe' value='1'></td>
As each ItemView is being created I want to check if the status returned by the server is the same value as the input value ie either 0,1, or 2 and if it is set that element to selected.
Recipe = Marionette.ItemView.extend({
ui: {
comm: 'input[type=radio]'
},
onBeforeRender: function () {
for (var i = 0; i < this.ui.comm.length; i++) {
if(parseInt(this.ui.comm[i].value, 10) === this.model.get('status')) {
this.ui.comm[i].$el.prop('selected')
}
}
}
However, when I view the interface none of the radio buttons have a check in them.
When I debug the code I can see that the line this.ui.comm[i].$el.prop('selected) is being executed so I'm wondering why doesn't it display set the element to selected? BTW I tried using that function on the onRender event also but the same result

I disagree with your approach, instead of having a onBeforeRender function whose whole function is to check the "state" and set it to checked. I would move that "logic" to the template and not have it handled in the view.
Your template would look something like:
<td><input type='radio' name='<%- id %>-typeRecipe' <% if (status == '0') { %>checked='checked'<% } %>value='0'></td>
<td><input type='radio' name='<%- id %>-typeRecipe' <% if (status == '2') { %>checked='checked'<% } %>value='2'></td>
<td><input type='radio' name='<%- id %>-typeRecipe' <% if (status == '1') { %>checked='checked'<% } %>value='1'></td>
and finally your render'er?? lol. would just look something like:
this.$el.html(this.template(this.model.toJSON()));
This again is "my opinion" and you can handle it as you see fit, but i like it because that sort of mundane logic clutters the views and just leaves the person behind you reading more code than he/she has too. And ... i think this approach is more "elegant" because that loop you have going on can be avoided completely.

It is the checked property for radio inputs, not selected. Also you will want to set the second argument to true, to actually set value for that property, or you're just getting it otherwise.
$('input.selectMe').prop('checked', true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='radio' name='typeRecipe' value='0'>
<input type='radio' name='typeRecipe' value='2' class="selectMe">
<input type='radio' name='typeRecipe' value='1'>

Related

How to shift + click to select multiple checkboxes using checklist-model directive?

Is there any way to shift + click to select multiple checkboxes using this directive like we have in Gmail?
Example:
Click on 1st row's checkbox.
Holding down SHIFT key.
Click on 10th row's checkbox.
Result: the first 10th rows will be selected.
Here is an example of how to do it, the selectors will need to be changed to something more specific when it is used in something with more that just the check-boxes.
It works by scanning all the inputs and seeing if it is checked, if it is it toggles a boolean that will cause each element to toggle to checked until the this matches the clicked item then breaks out of the loop as it doesnt need to check any more.
$("[type='checkbox']").click(function(evt) {
if (evt.shiftKey){
let item = $(this);
let hitfirstChecked = false;
$("#wrapper-check input").each(function(){
if($(this).is(":checked")){
hitfirstChecked = true;
}
if(hitfirstChecked){
$(this).prop('checked', true);
}
if(item.is($(this))){
return false;
}
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="wrapper-check">
<input type="checkbox" value="1">1
<input type="checkbox" value="2">2
<input type="checkbox" value="3">3
<input type="checkbox" value="4">4
<input type="checkbox" value="5">5
<input type="checkbox" value="6">6
<input type="checkbox" value="7">7
<input type="checkbox" value="8">8
</span>

Setting readonly using ng-readonly dynamically is not working

I am fetching some data from the database server and displaying the same in tabular format on my GUI. I want to achieve the following in my GUI design
(a) Any cell in the table should be editable except the first column in the table.
(b) The first row of the table, if added newly to the GUI for accepting new inputs from the user, should be exempted from the above rule i.e., all columns of the first row should be editable.
To achieve this I wrote the following code.
HTML Code
<tbody>
<tr ng-repeat="x in sensordata">
<td>
<input class="form-control" type="text" ng-model="x.name" placeholder="Sensor name" ng-readonly="namereadonly" ng-init="ctrl2.setReadOnly(x.name,$index)"/>
</td>
<td>
<input class="form-control" type="text" ng-model="x.unit" placeholder="Measurement Unit" required/>
</td>
<td>
<input class="form-control" type="text" ng-model="x.type" placeholder="Sensor Type" required/>
</td>
<td>
<input class="form-control" type="text" ng-model="x.periodicity" placeholder="Periodicity" required/>
</td>
<td>
<input class="form-control" type="text" ng-model="x.formula" placeholder="Formula" required/>
</td>
<td>
<input class="form-control" type="email" ng-model="x.vendor" placeholder="Email Id" required/>
</td>
</tr>
</tbody>
Controller code is as follows.
this.setReadOnly = function(name,idx) {
console.log('name ' + name + ' idx ' + idx);
if (name === undefined || name === null || name === '') $scope.namereadonly = false;
if (name !== '' || name !== undefined || name !== null) $scope.namereadonly = true;
};
When I am executing above code the first column of all the rows are getting uneditable as expected. But when I am adding new row to the (by adding new empty JSON object in the sensordata array in another function of the same controller) GUI, the first column of the row is getting uneditable which should not be the case as per the first if statement in the above method. I am unable to figure out why it is happening.
you can try if else statement, which sets the variable properly
this.setReadOnly = function(name,idx) {
console.log('name ' + name + ' idx ' + idx);
if (name === undefined || name === null || name === '') $scope.namereadonly = false;
else (name !== '' || name !== undefined || name !== null) $scope.namereadonly = true;
};
<input class="form-control" type="text" ng-model="x.name" placeholder="Sensor name" ng-model-options="{ updateOn: 'blur' }" ng-readonly="x.name.length"/> this line solved my problem. Without ng-model-options attribute as soon as one types a character in the newly added row the first column is becoming uneditable. With ng-model-options this issue is resolved as now the column would become uneditable upon moving focus from the input field.
No method is to be written in the controller.
you can put the condition directly in ng-readonly as below
<input class="form-control" type="text" ng-model="x.name" placeholder="Sensor name" ng-readonly="{{x.name !== '' && x.name !== undefined && x.name !== null}}" />
a) Any cell in the table should be editable except the first column in
the table. (b) The first row of the table, if added newly to the GUI
for accepting new inputs from the user, should be exempted from
the above rule i.e., all columns of the first row should be editable.
There are plenty solutions but it depends on you/your needs. Here I would like to share you 2 logics :
adding new key for the new object entered by user and use this new key to distinct them with old object ng-readonly="x.new" and new object should have this key: {name:"", new: true}
Store the length of main array, and use this to distinct the new object entered ng-readonly="$index < mainlength" and mainlength is something like: $scope.mainlength = angular.copy($scope.sensordata.length) (use of angular.copy ) see http://plnkr.co/edit/zCcyPTG3EybL4IjsOpz4?p=preview

angularjs change view on ng-model change

<select ng-model="Listbox" ng-options="build for build in builds" ng-change="show(Listbox); showtable(Listbox);showummary(Listbox);"style="width: 500px" id="lbox"></select>
Here on change of option i am calling all 3 functions but i want them to be called depending on which radio button is checked.
<tr><td >
<input type="radio" checked onclick="showF();">Summary
</td>
<td >
<input type="radio" onclick="showS();">Detailed Summary
</td>
</tr>
If summary is selected then only call show and showtable otherwise call showsummary. I can put them in radio buttion tag but then change in select option won't be deteced.
You can modify your ngChange to trigger a single function, as below:
<select ng-model="Listbox" ng-options="build for build in builds" ng-change="checkShow()"style="width: 500px" id="lbox"></select>
Then you change your radio buttons:
<input type="radio" value="summary" ng-model="radioSelected">Summary
<input type="radio" value="detailedSummary" ng-model="radioSelected">Detailed Summary
Note: Don't use onclick, use ngClick if you need to trigger a click event in Angular.
Finally, in your controller you can just check what's the option selected in radio:
$scope.radioSelected = 'summary'; // Default selection
$scope.checkShow = function() {
if ($scope.radioSelected === 'summary') {
show();
showTable();
} else {
showSummary();
}
}

angularjs: event before change the radio button value

How do I identify the change in value of a "radio button" before the current value change?
In my application, I need to alert the User about the effects that changing the value of this radio button will cause in the rest of form.
I've tried using ngChange and ngClick, but the value of the radio button is always changed (to the new value) even before I can do something with the current value.
Example:
<form>
<label>Nivel de gestão</label>
<input name="gestao" type="radio" data-ng-model="nivelGestao" value="T" data-ng-change="mudarNivelGestao()">Tecnica
<input name="gestao" type="radio" data-ng-model="nivelGestao" value="O" data-ng-change="mudarNivelGestao()">Operacional
<input name="gestao" type="radio" data-ng-model="nivelGestao" value="I" data-ng-change="mudarNivelGestao()">Institucional
<table>
<tr>
<td>Id</td>
<td>Nome</td>
</tr>
<tr data-ng-repeat="gestor in gestores">
<td>{{gestor.id}}</td>
<td>{{gestor.nome}}</td>
</tr>
</table>
<script>
...
$scope.mudarNivelGestao = function() {
alert($scope.nivelGestao); // In this place the content has already been changed, but before I need to alert and ask if the User want continue, if "No" return to the last value, if "Yes" change the value and go ahead...
...
}
...
</script>
</form>
I answered a similar question here
Just surround the radio input with label and apply the confirm logic in labels ng-click event.
<label ng-click="confirmChange($event)"><input type="radio" ng-model="value" value="foo" ></label>
$scope.confirmChange = function(event) {
if(!confirm('sure?')) {
event.preventDefault();
}
};
You can use the mousedown event (which will fire before the click and change events).
E.g.:
<input type="checkbox" ng-model="option"
ng-mousedown="confirmOption($event)" />
$scope.confirmOption = function (evt) {
var confirmMsg = 'Are you sure you want to select this ?';
if (!$scope.option) {
var confirmed = confirm(confirmMsg);
$scope.option = confirmed;
}
};
See, also, this short demo.

select all checkbox pagination help required

I currently have a report with pagination that displays 10 records Per page.
Within this report, I also have a checkbox column for every record. Based on this,
I want to incorporate a "Check All" feature, so based on my scenario which displays 10 records, when I press the "Check All" checkbox, I would like to check all the visible records (10 at a time) in that page (pageno=3) and after deleting those 10 records, the page should be redirected to the same page (filename.php) with same page number(pageno=3).
www.example.com/filename.php?pageno=3
Using some framework like jQuery will make your life a lot easier. Suppose following is structure of your records:
<table id="report">
<tr><td> <input type="checkbox" id="tr1" /></td><td>..</td><td>...</td></tr>
<tr><td> <input type="checkbox" id="tr2" /></td><td>..</td><td>...</td></tr>
<tr><td> <input type="checkbox" id="tr3" /></td><td>..</td><td>...</td></tr>
<tr><td> <input type="checkbox" id="tr4" /></td><td>..</td><td>...</td></tr>
<tr><td> <input type="checkbox" id="tr5" /></td><td>..</td><td>...</td></tr>
</table>
<input type="checkbox" id="chkAll"/> Select All.
The following code (using jquery) will do the needful:
<script type="text/javascript">
$(document).ready(function(){
$("#chkAll").change(function(){
if($("#chkAll").is(":checked")){
$("#report tr td:first-child").find("input:checkbox")
.attr("checked","checked");
}else{
$("#report tr td:first-child").find("input:checkbox")
.attr("checked","");
}
});
});
</script>
EDIT:- based on your code, try replacing your boxes_checkall function with this code;
function boxes_checkall(a,b)
{
var cbs=a.getElementsByTagName('input');
for(var i=0;i<cbs.length;i++)
{
if(cbs[i].type.toLowerCase()=='checkbox')
{
cbs[i].checked = b==1;
}
}
}
</script>
This could be solved using Javascript.
How do you define the names of the checkboxes?
You could do a for loop to change the status of all checkboxes that are shown at the moment.
If you're using a javascript toolkit/framework like jQuery this is very easy.
For instance you could give the class .page-[NUM] to all the checkboxes on a page and then use:
$(".page-[NUM]").each(function()
{
this.checked = checked_status;
});
Or if you use the same name for each checkbox on a page, try:
$("input[#name=thename]").each(function()
{
this.checked = checked_status;
});
where "thename" would be the name of your checkboxes on that page.

Resources