How to write this code cleaner, without repetition? [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
$("#yl").click(function(){updateYear("sub")});
$("#yr").click(function(){updateYear("add")});
$("#ml").click(function(){updateMonth("sub")});
$("#mr").click(function(){updateMonth("add")});
$("#dl").click(function(){updateDay("sub")});
$("#dr").click(function(){updateDay("add")});
Is there a way to write this code cleaner, smarter without repetitions?

If you change your elements a bit, you could do something like this:
<button id='yr' data-type='update' data-date-part='year' data-date-action='add'>
Then you create an update function that starts off like this:
function update() {
const el = $(this);
const datePart = el.attr('data-date-part');
const dateAction = el.attr('data-date-action');
// do your logic to update the date based on what part and action
}
Then your click handler just needs to be:
$('button[data-type="update"]').click(update);
I forgot to mention, that newer versions of jquery will also let you just use the .data() function instead of spelling out the full data- attribute

The code is fine as it stands as it is very clear what is happening.
If you really want to do it differently, then you should probably also modify your function(s) and look into HTML attributes. It all depends what you are actually doing in those functions.
If for instance you want the user to enter a date just by pressing add/sub buttons, then the basics could look like this:
$('.change-value').click(updateDatePart);
function updateDatePart() {
// Read current date
var dateParts = $.map($(this).closest(".dateinput").find(".part-value"), function (span) {
return +$(span).text();
});
// Which part of the date needs incrementing/decrementing?
var part = $(this).closest('.part').index();
// Apply change to that part
dateParts[part] += $(this).data("inc");
// Create a date with this
var date = new Date(dateParts[0], dateParts[1]-1, dateParts[2]);
// Get the parts for the new date (which may have resolved some overflow)
dateParts = [date.getFullYear(), date.getMonth()+1, date.getDate()];
// Output the result
$('.part-value').each(function (i, elem) {
$(elem).text(dateParts[i]);
});
}
.change-value { font-size: 50% }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="dateinput">
<span class="part">
<button class="change-value" data-inc="-1">-</button>
<span class="part-value">2017</span>
<button class="change-value" data-inc="1">+</button>
</span>-
<span class="part">
<button class="change-value" data-inc="-1">-</button>
<span class="part-value">12</span>
<button class="change-value" data-inc="1">+</button>
</span>-
<span class="part">
<button class="change-value" data-inc="-1">-</button>
<span class="part-value">24</span>
<button class="change-value" data-inc="1">+</button>
</span>
</span>

Related

Laravel - on click, pass the element id to function in the controller [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 months ago.
Improve this question
I have been struggling with this issue for a couple of days now...
In my home view I have a group of two buttons that are linked to another controller "BookingController". these two buttons have a variable id, that changes based on the value stored in the database. So what I wanna do is when the user click the first button "start button" a new record will be added in the "booking" table in database and one of the values that will be sotred in this record is the id of the element clicked. The problem is I can't figure a way to pass this id to the controller where I will use it in "addBooking" function. I would like to pass the id value to the function as a whole and modify the string in the controller function itself or after modifying it as a string here in the javascript.
here is the code simplified
`
#php
use App\Http\Controllers\BookingController;
#endphp
#push('js')
<script>
function reply_click(clicked_id)
{
if (clicked_id.indexOf(startTime) !== -1)
{
var roomID= clicked_id.replace("btnStart","");
** var booking = " <?php BookingController::addBooking(); ?> ";** <---- I want to pass the "roomID" var into "addBooking" function here
}
else if (clicked_id.indexOf(endTime) !== -1)
{
var roomID= clicked_id.replace("btnEnd","");
var booking = " <?php BookingController::updateBooking(); ?> ";
}
}
</script>
#endpush
#section('content')
<div class="btn-group">
<button onClick="reply_click(this.id)" id="btnStart{{ $room->id }}" type="button"></button>
<button onClick="reply_click(this.id)" id="btnEnd{{ $room->id }}" type="button"></button>
</div>
#endsection
`
I tried couple of ways but still not getting the value passed. I tried the cookies and it's working but it keeps adding the same record on each reload. I also tried the following
$.post ('app\Http\Controllers\BookingController.php', {room: roomID});
$.ajax ({ type: 'post', url: 'app\Http\Controllers\BookingController.php', data: {room= roomID}, sucess: function (data) { console.console.log(data);} });
'app\Http\Controllers\BookingController.php' is not a url. Use a valid url to point to your controller method.
Your ajax code should be something like this. I don't know what your route looks like, so point to the correct route.
$.ajax ({ method: 'post', url: '/booking/update', data: {room: roomID}, success: function (data) { console.log(data); } });

Reload Data with .sort from Dynamic Table with Jquery | JSON | Sort with New Data

I have been trying for a few days that when I use the .sort property the data is eliminated or modified instead of it being reloaded as new lines.
Attach Captures from the code Working
Image1 How work the code when i press the button, this sort to the highest price to lowest but how do you can see in the second image, the code appears up and this not delete the old data
Marked with "X" the data that does not have to show
this fragment is the one that generates the tables dynamically
const mostrarProductos = () => {
$.getJSON(URLJSON, (respuesta) => {
for (let z of respuesta) {
productosv2.push(z);
}
for (let x of productosv2) {
$("#fila").append(`
<tr class="deleteProductos">
<div class="card text-center" style="width: 18rem;" id='btnBorrarCarrito'>
<div class="card-body">
<input type="hidden" id="idProd" value="${x.id}"> </td>
<td class="card-title" id="${x.id}">${x.producto}</h2> </td>
<td class="card-text">$ ${x.precio}</p></td>
<div class="btn-group" role="group" aria-label="Basic mixed styles example">
<td><button type="button" class="btn btn-success" onclick="agregarCarrito(${x.id})">Agregar</button></td>
</div>
</div>
</div>
</tr>
`);
}
$("#fila").fadeIn("5000");
});
};
And this function is what orders them
function respuestaClickExpensive() {
$("#fila").html('');
let productosordenados = productosv2.sort((a, b) => {
if (a.precio > b.precio) {
return -1;
}
if (a.precio < b.precio) {
return 1;
}
return 0;
});
return productosordenados;
}
The one that orders them from smallest to largest is the same only that different signs and names.
As you can see I tried to use a ".html ("")" since previously in another cart attempt it used .innerHtml (Which does not work in this case either, Also the code of the cart is totally different from that moment that it worked for me
)
I tried the following:
$ ("#fila"). empty ();
Make another function to clean with .empty
Use Native JavaScript to generate the code.
$ ("#fila"). remove (); this removes all the content for me but does not regenerate it.
Change the HTML tag "Row" to a previous div which, since the div was not generated again, did not generate it again.
$ ("#fila tr"). remove ();
And some more things that I don't remember right now.
If you can guide me on what I did wrong or any suggestions to fix it, I appreciate it.
If I had to follow a template about posting on StackOverFlow or having chosen or named in a different way, I appreciate your comment since it is my first post
Project notes of possible relevance: The complete code outside of html and css is made with Native JavaScript, Jquery, Ajax, SASS and BootStrap.

Printing to the screen using innerHTML and innerText not working with my htmlCollection

This is not a duplicate so please don't close this. I did my research and already found what is considered a duplicate and it did not answer my quesiton. I want to modify all elements with the same class name in the dom so I already know the difference between getElementById and getElementsByClassName.
I have some code that almost works. I have to take a string, convert it to a number, then convert it back to a currency based string and then replace the text withing the innerHTML on screen. In my console.log, I am getting back the exact amounts I need for all the elements with the class="lh1em". I got everything working up until the point I have to replace the text with this new variable I have created with the new and improved data. I have tried to do it with a function, without a function but in both cases, I get no results, no errors except I get correct info in the console.log.
Here is my html:
<div class="price">
<span class="label">from</span>
<span class="value"><span class="text-lg lh1em item "> $3,845.00</span>
</span>
<br>
<span class="label">from</span>
<span class="value"><span class="text-lg lh1em item "> $3,645.00</span>
</span>
</div>
and my javascript
let customPrice = document.getElementsByClassName('lh1em');
Array.from(customPrice).forEach(function(dollarAmount) {
let withoutDollar = dollarAmount.innerText.substr(1);
let withoutComa = withoutDollar.replace(",",'');
let noPointZero = withoutComa.replace(/\.00/, '');
noPointZero = Number(noPointZero);
let newDollar = noPointZero - 600;
let formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
});
let doubleOccupancyPrice = formatter.format(newDollar);
function changeText() {
document.getElementsByClassName('lh1em').innerHTML = doubleOccupancyPrice;
}
changeText();
console.log(doubleOccupancyPrice);
});
If anyone can show me what I am doing wrong, I would sure appreicate it. Thank you in advance.
Credit goes to #pilchard for helping me come up with the answer to this.
I just had to replace my function with the following code:
dollarAmount.innerHTML = doubleOccupancyPrice;
With that, I was able to get the right info both in cosole and on the dom

AngularJs/Javascript , Copy Object is good practice? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
i'm wrote some todo list app, to understand how to be more expert.
what i'm try to understand:
my problem is when user click on task to edit, because it passed by reference so if user edit task, it will change directly the task object.
(i attached my code here).
my questions:
1) in my code i wrote one way to fix it, by clone object every time.
it good practice ? if no how you recommend me to fix it?
2) because i do not want my code only work, i want to be more expert.
if you think my thinking and planning of this code is bad? how you write this app? ( i talk here only about functional, add, edit, list of task)
thanks for help :)
link to plunker: https://plnkr.co/edit/CA99iiydbD4TWaGtJZZf?p=preview
code:
HTML
<html ng-app="todos">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="main">
<ul>
<li ng-repeat="task in todosBL.tasks" ng-click="editMode.edit(task)">{{ task.content}}</li>
</ul>
<input type="text" ng-model="task">
<input type="button" value="add task" ng-click="add(task)">
<!--//for edit-->
<div>
<input type="text" ng-model="editMode.task.content">
<input type="button" value="save task" ng-click="editMode.save(editMode.task)">
</div>
</div>
</body>
</html>
SCRIPT:
(function() {
var Task = (function() {
var counter = 0;
return function(content, isDone) {
this.id = counter++;
this.content = content;
this.isDone = isDone || false;
}
}());
var app = angular.module('todos',[])
.service('todosBL', function() {
this.tasks = [];
this.add = function(content) {
this.tasks.push(new Task(content));
}
this.update = function(editedTask) {
var i = this.tasks.findIndex(function(task){
return task.id === editedTask.id
});
this.tasks[i] = editedTask;
}
})
.controller('main', function($scope, todosBL) {
$scope.todosBL = todosBL;
$scope.add = function(task) {
todosBL.add(task);
$scope.task = null;
}
$scope.editMode = {
task: {},
edit: function(task) {
this.task = task;
//BECAUSE I PASS TASK BY REFERNCE WHEN USER EDIT TASK IT CHANGE TASK DIRECTLY ,
// IF I CLONE OBJECT EVERY TIME, IT FIX BY REFERENCE PROBLEM.
// MY QUESTION IF HAVE OTHER WAY TO SLOVE THIS. MABY OTHER WAY TO THINK ABOUT APP LIKE THIS.
// for(key in task) {
// this.task[key] = task[key];
// }
},
save: function(task) {
todosBL.update(task);
this.task = {};
}
};
});
}());
I think that your controller is over complicated. The service should implement some BL like data verification and posting it to the server and/or local storage but not searching for index, it does silly things now!
In order to satisfy all your requirements one just needs a controller:
app.controller('MainCtrl', function($scope) {
$scope.tasks = [];
$scope.add = function(content){
$scope.tasks.push(new Task(content));
$scope.content = null;
}
$scope.edit = function(task){
$scope.currentlyEditing = task;
$scope.editText = task.content;
}
$scope.save= function(){
$scope.currentlyEditing.content = $scope.editText;
$scope.editText = null;
$scope.currentlyEditing = null;
mySuperSeriousService.postToServer.then(result=> {
alert('Success');
})
}
});
and template like this:
<body ng-controller="MainCtrl">
<ul>
<li ng-repeat="task in tasks" ng-click="edit(task)">{{ task.content}}</li>
</ul>
<input type="text" ng-model="content">
<button ng-click="add(content)">Add Task</button>
<!--//for edit-->
<div>
<input type="text" ng-model="editText" ng-disabled="!currentlyEditing">
<button ng-click="save()">Save</button>
</div>
</body>
So it's 2 times shorter. Here's the plunker (https://plnkr.co/edit/nN8kd5ErSDsBu6Exm1YO)
my problem is when user click on task to edit, because it passed by reference so if user edit task, it will change directly the task object. (i attached my code here).
For solving this problem, you should make a copy of your model and change it (in edit function): this.task = angular.copy(task);
in my code i wrote one way to fix it, by clone object every time. it good practice ? if no how you recommend me to fix it?
As I said, making copy is much more logical !
because i do not want my code only work, i want to be more expert. if you think my thinking and planning of this code is bad? how you write this app? ( i talk here only about functional, add, edit, list of task)
1) I don't know why you are using an array of objects ? your tasks are just strings ! so it can be better if you use an array of strings. then you won't have the struggle with sth like editMode.task.content, you just use editMode.task !
2) Don't work with ids . cause when you add the 'Deleting Task' feature, you'll got problems ...
3) What does Task() function do ? ( In this case, you don't need sth like this)
4) ...

How to populate checkbox with JSON data [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a web page that receives the following JSON from a server
{"d":[
{"__type":"Service1.Operators:#MobileWCFService","operators":"ACCOUNTING"},
{"__type":"Service1.Operators:#MobileWCFService","operators":"AHOFFMAN"},
{"__type":"Service1.Operators:#MobileWCFService","operators":"AMONROY"},
{"__type":"Service1.Operators:#MobileWCFService","operators":"APATENTAS "},
{"__type":"Service1.Operators:#MobileWCFService","operators":"WRAMOS "}
]}
From the array d in this data I need to create checkboxes, each corresponding to an element of the array, defined by the operators property of each element. I need these checkboxes to be dynamically generated with JavaScript/jQuery once the data is received. How can this be done?
Is this what you want?
var input=//get input json
var data=input.d;
for(var x in data){
var type=data[x].__type;
var ops=data[x].operators;
var id="checkbox-"+ops+Math.floor(Math.random()*100000);
$("<div><label></label><input/></div>")
.children().eq(1)
.attr({
"type":"checkbox",
"name":"insert here",
"data-type":type,
"data-operators":ops,
"id":id,
"class": "your checkbox class here"
})
.click(function(){ /////////////////////////// updated here
if($(this).prop("checked")){
// do action for checked event
} else {
// do action for unchecked event
}
})
.parent()
.children().eq(0)
.attr("for", id)
.text("whatever label you want")
.parent()
.appendTo($("container you want to put them in"));
}
You should loop over JSON result and create checkbox element and add it to div. Use jquery .each() to loop JSON. Try this:
var json = {"d":[
{"__type":"Service1.Operators:#MobileWCFService","operators":"ACCOUNTING"},
{"__type":"Service1.Operators:#MobileWCFService","operators":"AHOFFMAN"},
{"__type":"Service1.Operators:#MobileWCFService","operators":"AMONROY"},
{"__type":"Service1.Operators:#MobileWCFService","operators":"APATENTAS "},
{"__type":"Service1.Operators:#MobileWCFService","operators":"WRAMOS "}
]};
$(document).ready(function() {
var $grouplist = $('#checkboxes');
$.each(json.d, function() {
$('<label>'+this.operators+': </label><input type=checkbox
value='+this.operators+'/>').appendTo($grouplist);
});
});
DEMO

Categories