Meitie
Meitie

Reputation: 75

having trouble Converting procedural JavaScript to a more OOP code version

I currently have built an add more system to generate more fields for users in a form and then also to check in query string if form fails. However it is done in a more procedural way in that each version is its own which leads me to having the similar code duplicated like 5 times (one for each version and for each function) and was wondering if you could help me convert it to more of a OOP way so it is only one set code to make it easier to run on my system and thus not making me run so much code and a more streamlined code

I have tried to make it somewhat OOP but i keep getting errors as I'm not very good at the JavaScript or OOP I got it to work basic JavaScript but that means i have so many extra lines of codes

So Here is the base code which works however it is like shown it will be duplicated 3 more times after these ones

<script>
<!-- MORE BIKES -->
var max_fields_morebikes = 4;
var wrapper_bike = $("#currentbikes");
var add_button_morebikes = $("#morebikes");
var counter_bikes = 1;

<!-- add and delete for morebikes -->
$(add_button_morebikes).click(function (e) {
    e.preventDefault();
    if (counter_bikes < max_fields_morebikes) {
        counter_bikes++;
        $(wrapper_bike).append('<div class="morebikesadd"><input type="text" name="currentbike[]" class="currentbikesadd" placeholder="Current Bikes" ><button class="delete">Delete</button></div>');
        //add input box
    } else {
        alert('You Reached the limits')
    }
});
$(wrapper_bike).on("click", ".delete", function (e) {
    e.preventDefault();
    $(this).parent('div').remove();
    counter_bikes--;
});
</script>

and also have versions where there is adding 2 sets of inputs

<script>
<!-- RACES HISTORY -->
var max_fields_racehist = 5;
var wrapper_racehist = $("#racinghistoryresults");
var add_button_racehist = $("#moreracehist");
var counter_racehist = 1;

<!-- add and delete for RaceHistory -->
$(add_button_racehist).click(function (e) {
    e.preventDefault();
    if (counter_racehist < max_fields_racehist) {
        counter_racehist++;
        $(wrapper_racehist).append('<div style=" margin-top: 10px; margin-bottom: 10px;"><input type="text" name="racehist[]" class="racehist addmoreracehistory" placeholder="Race History">&nbsp;<input type="text" name="results[]" class="results addmorementionableresults" placeholder="Mentionable Results">&nbsp;<button class="delete">Delete</button></div>');
        //add input box
    } else {
        alert('You Reached the limits')
    }
});
$(wrapper_racehist).on("click", ".delete", function (e) {
    e.preventDefault();
    $(this).parent('div').remove();
    counter_racehist--;
});
</script>

This is the method I tried for at least if there is one input

<button type="button" onclick="return addMoreRows(5,1, 'morebikesadd', 'currentbike','currentbikesadd','Current Bike', 'delete')"> Add More</button>
<script>
 function addMoreRows(numFields, maxCounter, addMoreClass, inputName, inputClass, placeHolderName,buttonClass){
        var max_fields = numFields;
        var wrapper = document.createElement("div");
        var counter = maxCounter;

        if (counter < max_fields) {
            counter++;
            wrapper.appendChild('<div class="' + addMoreClass + '"><input type="text" name="'+ inputName +'[]" class="'+ inputClass +'" placeholder="'+ placeHolderName +'"><button class="'+ buttonClass +'"> Delete </button></div>');
        }
        else {
            alert('You Have Reached the limits')
        }

    }
</script>

I want to know if possible how i can combine it so that it will just take in the values i put into and work so i only need 1 maybe 2 functions (depends if it can combine the only 1 inputs and 2 inputs) so that I can do onclick=" addMoreRows(values,values,etc)" so that can be done easier

Upvotes: 0

Views: 33

Answers (1)

Adnan Sharif
Adnan Sharif

Reputation: 967

According to your question, you want want to code such as you don't need to write same type of functions multiple time.

In your code there are are two type: bikes and raceHistory. They have similar properties such as maxLimit, currentCount, selector and html for new element.
So, you can make an object like the following:

var itemTypes = {
    bike:{
        maxLimit: 4,
        currentCount: 1,
        selector: '#currentbikes',
        newElement: '<div class="morebikesadd"><input type="text" name="currentbike[]" class="currentbikesadd" placeholder="Current Bikes" ><button class="delete">Delete</button></div>'
    },
    raceHistory:{
        maxLimit: 5,
        currentCount: 1,
        selector: '#racinghistoryresults',
        newElement: '<div style=" margin-top: 10px; margin-bottom: 10px;"><input type="text" name="racehist[]" class="racehist addmoreracehistory" placeholder="Race History">&nbsp;<input type="text" name="results[]" class="results addmorementionableresults" placeholder="Mentionable Results">&nbsp;<button class="delete">Delete</button></div>'
    }
}

From you html, just send your type as an argument for your addMoreRows() function, for example, for bike use following:

<button type="button" onclick="return addMoreRows('bike')"> Add More Bike</button>

OR use the following for raceHistory

<button type="button" onclick="addMoreRows('raceHistory')"> Add More Race History</button>

and handle from your addMoreRows() function like this

function addMoreRows(type){
    var item = itemTypes[type];
    if (item.currentCount < item.maxLimit) {
        item.currentCount++;
        $(item.selector).append(item.newElement);
    }
    else {
        alert('You Have Reached the limits')
    }
}

Hola! Everything is now generalized!

If you want to add another type, for example, motorBike, then just update your itemTypes Object like the following:

var itemTypes = {
    bike:{
        maxLimit: 4,
        currentCount: 1,
        selector: '#currentbikes',
        newElement: '<div class="morebikesadd"><input type="text" name="currentbike[]" class="currentbikesadd" placeholder="Current Bikes" ><button class="delete">Delete</button></div>'
    },
    raceHistory:{
        maxLimit: 5,
        currentCount: 1,
        selector: '#racinghistoryresults',
        newElement: '<div style=" margin-top: 10px; margin-bottom: 10px;"><input type="text" name="racehist[]" class="racehist addmoreracehistory" placeholder="Race History">&nbsp;<input type="text" name="results[]" class="results addmorementionableresults" placeholder="Mentionable Results">&nbsp;<button class="delete">Delete</button></div>'
    },
    motorBike:{
        maxLimit: 10,
        currentCount: 1,
        selector: '#selectorformotorbike',
        newElement: '<div>Put your desired code for new element</div>'
    }
}

You don't need do anything in your javascript for new changes!

Here is the working code:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>

<button type="button" onclick="addMoreRows('raceHistory')"> Add More Race History</button>

<div id="racinghistoryresults">
</div>

<script>
var itemTypes = {
    bike:{
        maxLimit: 4,
        currentCount: 1,
        selector: '#currentbikes',
        newElement: '<div class="morebikesadd"><input type="text" name="currentbike[]" class="currentbikesadd" placeholder="Current Bikes" ><button class="delete" onclick="deleteRow(this, \'bike\')">Delete</button></div>'
    },
    raceHistory:{
        maxLimit: 5,
        currentCount: 1,
        selector: '#racinghistoryresults',
        newElement: '<div style=" margin-top: 10px; margin-bottom: 10px;"><input type="text" name="racehist[]" class="racehist addmoreracehistory" placeholder="Race History">&nbsp;<input type="text" name="results[]" class="results addmorementionableresults" placeholder="Mentionable Results">&nbsp;<button class="delete" onclick="deleteRow(this, \'raceHistory\')">Delete</button></div>'
    }
}

function addMoreRows(type){
    var item = itemTypes[type];
    if (item.currentCount < item.maxLimit) {
        item.currentCount++;
        $(item.selector).append(item.newElement);
    }
    else {
        alert('You Have Reached the limits')
    }
}

function deleteRow(event, type){
  $(event).parent('div').remove();
  itemTypes[type].currentCount--;
};
</script>

Hope, this helps you!

Upvotes: 1

Related Questions